Merge branch 'master' of https://gitee.com/sunsz/RuoYi-Vue
# Conflicts: # ruoyi-ui/package.json
This commit is contained in:
@ -14,7 +14,7 @@ public class RuoYiApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// System.setProperty("spring.devtools.restart.enabled", "false");
|
||||
System.setProperty("spring.devtools.restart.enabled", "false");
|
||||
SpringApplication.run(RuoYiApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
|
@ -48,7 +48,7 @@ public class GenConstants
|
||||
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
|
||||
|
||||
/** Tree基类字段 */
|
||||
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" };
|
||||
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
|
||||
|
||||
/** 文本框 */
|
||||
public static final String HTML_INPUT = "input";
|
||||
|
@ -0,0 +1,50 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 任务调度通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ScheduleConstants
|
||||
{
|
||||
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
|
||||
|
||||
/** 执行目标key */
|
||||
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
|
||||
|
||||
/** 默认 */
|
||||
public static final String MISFIRE_DEFAULT = "0";
|
||||
|
||||
/** 立即触发执行 */
|
||||
public static final String MISFIRE_IGNORE_MISFIRES = "1";
|
||||
|
||||
/** 触发一次执行 */
|
||||
public static final String MISFIRE_FIRE_AND_PROCEED = "2";
|
||||
|
||||
/** 不触发立即执行 */
|
||||
public static final String MISFIRE_DO_NOTHING = "3";
|
||||
|
||||
public enum Status
|
||||
{
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL("0"),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE("1");
|
||||
|
||||
private String value;
|
||||
|
||||
private Status(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.ruoyi.common.exception.job;
|
||||
|
||||
/**
|
||||
* 计划策略异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TaskException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Code code;
|
||||
|
||||
public TaskException(String msg, Code code)
|
||||
{
|
||||
this(msg, code, null);
|
||||
}
|
||||
|
||||
public TaskException(String msg, Code code, Exception nestedEx)
|
||||
{
|
||||
super(msg, nestedEx);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Code getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public enum Code
|
||||
{
|
||||
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Repeatable 过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatableFilter implements Filter
|
||||
{
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
ServletRequest requestWrapper = null;
|
||||
if (request instanceof HttpServletRequest)
|
||||
{
|
||||
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
||||
}
|
||||
if (null == requestWrapper)
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
chain.doFilter(requestWrapper, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import com.ruoyi.common.utils.http.HttpHelper;
|
||||
|
||||
/**
|
||||
* 构建可重复读取inputStream的request
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
|
||||
{
|
||||
private final byte[] body;
|
||||
|
||||
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
|
||||
{
|
||||
super(request);
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
body = HttpHelper.getBodyString(request).getBytes("UTF-8");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException
|
||||
{
|
||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException
|
||||
{
|
||||
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||
|
||||
return new ServletInputStream()
|
||||
{
|
||||
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
return bais.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.ruoyi.common.xss;
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
@ -1,4 +1,4 @@
|
||||
package com.ruoyi.common.xss;
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
/**
|
||||
* 错误信息处理类。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class ExceptionUtil
|
||||
{
|
||||
/**
|
||||
* 获取exception的详细错误信息。
|
||||
*/
|
||||
public static String getExceptionMessage(Throwable e)
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw, true));
|
||||
String str = sw.toString();
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String getRootErrorMseeage(Exception e)
|
||||
{
|
||||
Throwable root = ExceptionUtils.getRootCause(e);
|
||||
root = (root == null ? e : root);
|
||||
if (root == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
String msg = root.getMessage();
|
||||
if (msg == null)
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
return StringUtils.defaultString(msg);
|
||||
}
|
||||
}
|
110
ruoyi/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java
Normal file
110
ruoyi/src/main/java/com/ruoyi/common/utils/bean/BeanUtils.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.ruoyi.common.utils.bean;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Bean 工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BeanUtils extends org.springframework.beans.BeanUtils
|
||||
{
|
||||
/** Bean方法名中属性名开始的下标 */
|
||||
private static final int BEAN_METHOD_PROP_INDEX = 3;
|
||||
|
||||
/** * 匹配getter方法的正则表达式 */
|
||||
private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
|
||||
|
||||
/** * 匹配setter方法的正则表达式 */
|
||||
private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
|
||||
|
||||
/**
|
||||
* Bean属性复制工具方法。
|
||||
*
|
||||
* @param dest 目标对象
|
||||
* @param src 源对象
|
||||
*/
|
||||
public static void copyBeanProp(Object dest, Object src)
|
||||
{
|
||||
try
|
||||
{
|
||||
copyProperties(src, dest);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的setter方法。
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 对象的setter方法列表
|
||||
*/
|
||||
public static List<Method> getSetterMethods(Object obj)
|
||||
{
|
||||
// setter方法列表
|
||||
List<Method> setterMethods = new ArrayList<Method>();
|
||||
|
||||
// 获取所有方法
|
||||
Method[] methods = obj.getClass().getMethods();
|
||||
|
||||
// 查找setter方法
|
||||
|
||||
for (Method method : methods)
|
||||
{
|
||||
Matcher m = SET_PATTERN.matcher(method.getName());
|
||||
if (m.matches() && (method.getParameterTypes().length == 1))
|
||||
{
|
||||
setterMethods.add(method);
|
||||
}
|
||||
}
|
||||
// 返回setter方法列表
|
||||
return setterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的getter方法。
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 对象的getter方法列表
|
||||
*/
|
||||
|
||||
public static List<Method> getGetterMethods(Object obj)
|
||||
{
|
||||
// getter方法列表
|
||||
List<Method> getterMethods = new ArrayList<Method>();
|
||||
// 获取所有方法
|
||||
Method[] methods = obj.getClass().getMethods();
|
||||
// 查找getter方法
|
||||
for (Method method : methods)
|
||||
{
|
||||
Matcher m = GET_PATTERN.matcher(method.getName());
|
||||
if (m.matches() && (method.getParameterTypes().length == 0))
|
||||
{
|
||||
getterMethods.add(method);
|
||||
}
|
||||
}
|
||||
// 返回getter方法列表
|
||||
return getterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Bean方法名中的属性名是否相等。<br>
|
||||
* 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
|
||||
*
|
||||
* @param m1 方法名1
|
||||
* @param m2 方法名2
|
||||
* @return 属性名一样返回true,否则返回false
|
||||
*/
|
||||
|
||||
public static boolean isMethodPropEquals(String m1, String m2)
|
||||
{
|
||||
return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
|
||||
}
|
||||
}
|
@ -144,7 +144,7 @@ public class EscapeUtil
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String html = "<script>alert(1);</script>";
|
||||
String html = "alert('11111');";
|
||||
System.out.println(EscapeUtil.clean(html));
|
||||
System.out.println(EscapeUtil.escape(html));
|
||||
System.out.println(EscapeUtil.unescape(html));
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.ruoyi.common.utils.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import javax.servlet.ServletRequest;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 通用http工具封装
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class HttpHelper
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
|
||||
|
||||
public static String getBodyString(ServletRequest request)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BufferedReader reader = null;
|
||||
try (InputStream inputStream = request.getInputStream())
|
||||
{
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
|
||||
String line = "";
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.warn("getBodyString出现问题!");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.error(ExceptionUtils.getFullStackTrace(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.http.HttpUtils;
|
||||
import com.ruoyi.framework.config.RuoYiConfig;
|
||||
|
||||
/**
|
||||
* 获取地址类
|
||||
@ -25,17 +26,20 @@ public class AddressUtils
|
||||
{
|
||||
return "内网IP";
|
||||
}
|
||||
String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip);
|
||||
if (StringUtils.isEmpty(rspStr))
|
||||
if (RuoYiConfig.isAddressEnabled())
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
return address;
|
||||
String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip);
|
||||
if (StringUtils.isEmpty(rspStr))
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
return address;
|
||||
}
|
||||
JSONObject obj = JSONObject.parseObject(rspStr);
|
||||
JSONObject data = obj.getObject("data", JSONObject.class);
|
||||
String region = data.getString("region");
|
||||
String city = data.getString("city");
|
||||
address = region + " " + city;
|
||||
}
|
||||
JSONObject obj = JSONObject.parseObject(rspStr);
|
||||
JSONObject data = obj.getObject("data", JSONObject.class);
|
||||
String region = data.getString("region");
|
||||
String city = data.getString("city");
|
||||
address = region + " " + city;
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import java.util.Date;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.utils.ExceptionUtil;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.bean.BeanUtils;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
import com.ruoyi.project.monitor.domain.SysJobLog;
|
||||
import com.ruoyi.project.monitor.service.ISysJobLogService;
|
||||
|
||||
/**
|
||||
* 抽象quartz调用
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public abstract class AbstractQuartzJob implements Job
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
|
||||
|
||||
/**
|
||||
* 线程本地变量
|
||||
*/
|
||||
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException
|
||||
{
|
||||
SysJob sysJob = new SysJob();
|
||||
BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
|
||||
try
|
||||
{
|
||||
before(context, sysJob);
|
||||
if (sysJob != null)
|
||||
{
|
||||
doExecute(context, sysJob);
|
||||
}
|
||||
after(context, sysJob, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("任务执行异常 - :", e);
|
||||
after(context, sysJob, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行前
|
||||
*
|
||||
* @param context 工作执行上下文对象
|
||||
* @param sysJob 系统计划任务
|
||||
*/
|
||||
protected void before(JobExecutionContext context, SysJob sysJob)
|
||||
{
|
||||
threadLocal.set(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行后
|
||||
*
|
||||
* @param context 工作执行上下文对象
|
||||
* @param sysScheduleJob 系统计划任务
|
||||
*/
|
||||
protected void after(JobExecutionContext context, SysJob sysJob, Exception e)
|
||||
{
|
||||
Date startTime = threadLocal.get();
|
||||
threadLocal.remove();
|
||||
|
||||
final SysJobLog sysJobLog = new SysJobLog();
|
||||
sysJobLog.setJobName(sysJob.getJobName());
|
||||
sysJobLog.setJobGroup(sysJob.getJobGroup());
|
||||
sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
|
||||
sysJobLog.setStartTime(startTime);
|
||||
sysJobLog.setStopTime(new Date());
|
||||
long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
|
||||
sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
|
||||
if (e != null)
|
||||
{
|
||||
sysJobLog.setStatus(Constants.FAIL);
|
||||
String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
|
||||
sysJobLog.setExceptionInfo(errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
sysJobLog.setStatus(Constants.SUCCESS);
|
||||
}
|
||||
|
||||
// 写入数据库当中
|
||||
SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行方法,由子类重载
|
||||
*
|
||||
* @param context 工作执行上下文对象
|
||||
* @param sysJob 系统计划任务
|
||||
* @throws Exception 执行过程中的异常
|
||||
*/
|
||||
protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import org.quartz.CronExpression;
|
||||
|
||||
/**
|
||||
* cron表达式工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class CronUtils
|
||||
{
|
||||
/**
|
||||
* 返回一个布尔值代表一个给定的Cron表达式的有效性
|
||||
*
|
||||
* @param cronExpression Cron表达式
|
||||
* @return boolean 表达式是否有效
|
||||
*/
|
||||
public static boolean isValid(String cronExpression)
|
||||
{
|
||||
return CronExpression.isValidExpression(cronExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个字符串值,表示该消息无效Cron表达式给出有效性
|
||||
*
|
||||
* @param cronExpression Cron表达式
|
||||
* @return String 无效时返回表达式错误描述,如果有效返回null
|
||||
*/
|
||||
public static String getInvalidMessage(String cronExpression)
|
||||
{
|
||||
try
|
||||
{
|
||||
new CronExpression(cronExpression);
|
||||
return null;
|
||||
}
|
||||
catch (ParseException pe)
|
||||
{
|
||||
return pe.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回下一个执行时间根据给定的Cron表达式
|
||||
*
|
||||
* @param cronExpression Cron表达式
|
||||
* @return Date 下次Cron表达式执行时间
|
||||
*/
|
||||
public static Date getNextExecution(String cronExpression)
|
||||
{
|
||||
try
|
||||
{
|
||||
CronExpression cron = new CronExpression(cronExpression);
|
||||
return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 任务执行工具
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JobInvokeUtil
|
||||
{
|
||||
/**
|
||||
* 执行方法
|
||||
*
|
||||
* @param sysJob 系统任务
|
||||
*/
|
||||
public static void invokeMethod(SysJob sysJob) throws Exception
|
||||
{
|
||||
String invokeTarget = sysJob.getInvokeTarget();
|
||||
String beanName = getBeanName(invokeTarget);
|
||||
String methodName = getMethodName(invokeTarget);
|
||||
List<Object[]> methodParams = getMethodParams(invokeTarget);
|
||||
|
||||
if (!isValidClassName(beanName))
|
||||
{
|
||||
Object bean = SpringUtils.getBean(beanName);
|
||||
invokeMethod(bean, methodName, methodParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
Object bean = Class.forName(beanName).newInstance();
|
||||
invokeMethod(bean, methodName, methodParams);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用任务方法
|
||||
*
|
||||
* @param bean 目标对象
|
||||
* @param methodName 方法名称
|
||||
* @param methodParams 方法参数
|
||||
*/
|
||||
private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams)
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
{
|
||||
if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0)
|
||||
{
|
||||
Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams));
|
||||
method.invoke(bean, getMethodParamsValue(methodParams));
|
||||
}
|
||||
else
|
||||
{
|
||||
Method method = bean.getClass().getDeclaredMethod(methodName);
|
||||
method.invoke(bean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否为为class包名
|
||||
*
|
||||
* @param str 名称
|
||||
* @return true是 false否
|
||||
*/
|
||||
public static boolean isValidClassName(String invokeTarget)
|
||||
{
|
||||
return StringUtils.countMatches(invokeTarget, ".") > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取bean名称
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return bean名称
|
||||
*/
|
||||
public static String getBeanName(String invokeTarget)
|
||||
{
|
||||
String beanName = StringUtils.substringBefore(invokeTarget, "(");
|
||||
return StringUtils.substringBeforeLast(beanName, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取bean方法
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return method方法
|
||||
*/
|
||||
public static String getMethodName(String invokeTarget)
|
||||
{
|
||||
String methodName = StringUtils.substringBefore(invokeTarget, "(");
|
||||
return StringUtils.substringAfterLast(methodName, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取method方法参数相关列表
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return method方法相关参数列表
|
||||
*/
|
||||
public static List<Object[]> getMethodParams(String invokeTarget)
|
||||
{
|
||||
String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")");
|
||||
if (StringUtils.isEmpty(methodStr))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String[] methodParams = methodStr.split(",");
|
||||
List<Object[]> classs = new LinkedList<>();
|
||||
for (int i = 0; i < methodParams.length; i++)
|
||||
{
|
||||
String str = StringUtils.trimToEmpty(methodParams[i]);
|
||||
// String字符串类型,包含'
|
||||
if (StringUtils.contains(str, "'"))
|
||||
{
|
||||
classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class });
|
||||
}
|
||||
// boolean布尔类型,等于true或者false
|
||||
else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false"))
|
||||
{
|
||||
classs.add(new Object[] { Boolean.valueOf(str), Boolean.class });
|
||||
}
|
||||
// long长整形,包含L
|
||||
else if (StringUtils.containsIgnoreCase(str, "L"))
|
||||
{
|
||||
classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class });
|
||||
}
|
||||
// double浮点类型,包含D
|
||||
else if (StringUtils.containsIgnoreCase(str, "D"))
|
||||
{
|
||||
classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class });
|
||||
}
|
||||
// 其他类型归类为整形
|
||||
else
|
||||
{
|
||||
classs.add(new Object[] { Integer.valueOf(str), Integer.class });
|
||||
}
|
||||
}
|
||||
return classs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数类型
|
||||
*
|
||||
* @param methodParams 参数相关列表
|
||||
* @return 参数类型列表
|
||||
*/
|
||||
public static Class<?>[] getMethodParamsType(List<Object[]> methodParams)
|
||||
{
|
||||
Class<?>[] classs = new Class<?>[methodParams.size()];
|
||||
int index = 0;
|
||||
for (Object[] os : methodParams)
|
||||
{
|
||||
classs[index] = (Class<?>) os[1];
|
||||
index++;
|
||||
}
|
||||
return classs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数值
|
||||
*
|
||||
* @param methodParams 参数相关列表
|
||||
* @return 参数值列表
|
||||
*/
|
||||
public static Object[] getMethodParamsValue(List<Object[]> methodParams)
|
||||
{
|
||||
Object[] classs = new Object[methodParams.size()];
|
||||
int index = 0;
|
||||
for (Object[] os : methodParams)
|
||||
{
|
||||
classs[index] = (Object) os[0];
|
||||
index++;
|
||||
}
|
||||
return classs;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务处理(禁止并发执行)
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
@DisallowConcurrentExecution
|
||||
public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob
|
||||
{
|
||||
@Override
|
||||
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
|
||||
{
|
||||
JobInvokeUtil.invokeMethod(sysJob);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import org.quartz.JobExecutionContext;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务处理(允许并发执行)
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class QuartzJobExecution extends AbstractQuartzJob
|
||||
{
|
||||
@Override
|
||||
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
|
||||
{
|
||||
JobInvokeUtil.invokeMethod(sysJob);
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package com.ruoyi.common.utils.job;
|
||||
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.TriggerKey;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.common.exception.job.TaskException.Code;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class ScheduleUtils
|
||||
{
|
||||
/**
|
||||
* 得到quartz任务类
|
||||
*
|
||||
* @param sysJob 执行计划
|
||||
* @return 具体执行任务类
|
||||
*/
|
||||
private static Class<? extends Job> getQuartzJobClass(SysJob sysJob)
|
||||
{
|
||||
boolean isConcurrent = "0".equals(sysJob.getConcurrent());
|
||||
return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务触发对象
|
||||
*/
|
||||
public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
|
||||
{
|
||||
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务键对象
|
||||
*/
|
||||
public static JobKey getJobKey(Long jobId, String jobGroup)
|
||||
{
|
||||
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建定时任务
|
||||
*/
|
||||
public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
|
||||
{
|
||||
Class<? extends Job> jobClass = getQuartzJobClass(job);
|
||||
// 构建job信息
|
||||
Long jobId = job.getJobId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
|
||||
|
||||
// 表达式调度构建器
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
|
||||
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
|
||||
|
||||
// 按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
|
||||
.withSchedule(cronScheduleBuilder).build();
|
||||
|
||||
// 放入参数,运行时的方法可以获取
|
||||
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
|
||||
|
||||
// 判断是否存在
|
||||
if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
|
||||
{
|
||||
// 防止创建时存在数据问题 先移除,然后在执行创建操作
|
||||
scheduler.deleteJob(getJobKey(jobId, jobGroup));
|
||||
}
|
||||
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
|
||||
// 暂停任务
|
||||
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
|
||||
{
|
||||
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定时任务策略
|
||||
*/
|
||||
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
|
||||
throws TaskException
|
||||
{
|
||||
switch (job.getMisfirePolicy())
|
||||
{
|
||||
case ScheduleConstants.MISFIRE_DEFAULT:
|
||||
return cb;
|
||||
case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
|
||||
return cb.withMisfireHandlingInstructionIgnoreMisfires();
|
||||
case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
|
||||
return cb.withMisfireHandlingInstructionFireAndProceed();
|
||||
case ScheduleConstants.MISFIRE_DO_NOTHING:
|
||||
return cb.withMisfireHandlingInstructionDoNothing();
|
||||
default:
|
||||
throw new TaskException("The task misfire policy '" + job.getMisfirePolicy()
|
||||
+ "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package com.ruoyi.common.utils.text;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class CharsetKit
|
||||
{
|
||||
/** ISO-8859-1 */
|
||||
public static final String ISO_8859_1 = "ISO-8859-1";
|
||||
/** UTF-8 */
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
/** GBK */
|
||||
public static final String GBK = "GBK";
|
||||
|
||||
/** ISO-8859-1 */
|
||||
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
|
||||
/** UTF-8 */
|
||||
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
|
||||
/** GBK */
|
||||
public static final Charset CHARSET_GBK = Charset.forName(GBK);
|
||||
|
||||
/**
|
||||
* 转换为Charset对象
|
||||
*
|
||||
* @param charset 字符集,为空则返回默认字符集
|
||||
* @return Charset
|
||||
*/
|
||||
public static Charset charset(String charset)
|
||||
{
|
||||
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, String srcCharset, String destCharset)
|
||||
{
|
||||
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, Charset srcCharset, Charset destCharset)
|
||||
{
|
||||
if (null == srcCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
if (null == destCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
return new String(source.getBytes(srcCharset), destCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 系统字符集编码
|
||||
*/
|
||||
public static String systemCharset()
|
||||
{
|
||||
return Charset.defaultCharset().name();
|
||||
}
|
||||
}
|
@ -1,999 +0,0 @@
|
||||
package com.ruoyi.common.utils.text;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Set;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 类型转换器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Convert
|
||||
{
|
||||
/**
|
||||
* 转换为字符串<br>
|
||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String toStr(Object value, String defaultValue)
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof String)
|
||||
{
|
||||
return (String) value;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符串<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String toStr(Object value)
|
||||
{
|
||||
return toStr(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符<br>
|
||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Character toChar(Object value, Character defaultValue)
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Character)
|
||||
{
|
||||
return (Character) value;
|
||||
}
|
||||
|
||||
final String valueStr = toStr(value, null);
|
||||
return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Character toChar(Object value)
|
||||
{
|
||||
return toChar(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为byte<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Byte toByte(Object value, Byte defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Byte)
|
||||
{
|
||||
return (Byte) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).byteValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Byte.parseByte(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为byte<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Byte toByte(Object value)
|
||||
{
|
||||
return toByte(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Short<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Short toShort(Object value, Short defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Short)
|
||||
{
|
||||
return (Short) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).shortValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Short.parseShort(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Short<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Short toShort(Object value)
|
||||
{
|
||||
return toShort(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Number<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Number toNumber(Object value, Number defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return (Number) value;
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return NumberFormat.getInstance().parse(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Number<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Number toNumber(Object value)
|
||||
{
|
||||
return toNumber(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为int<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer toInt(Object value, Integer defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Integer)
|
||||
{
|
||||
return (Integer) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为int<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer toInt(Object value)
|
||||
{
|
||||
return toInt(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Integer数组<br>
|
||||
*
|
||||
* @param str 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer[] toIntArray(String str)
|
||||
{
|
||||
return toIntArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Long数组<br>
|
||||
*
|
||||
* @param str 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long[] toLongArray(String str)
|
||||
{
|
||||
return toLongArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Integer数组<br>
|
||||
*
|
||||
* @param split 分隔符
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer[] toIntArray(String split, String str)
|
||||
{
|
||||
if (StringUtils.isEmpty(str))
|
||||
{
|
||||
return new Integer[] {};
|
||||
}
|
||||
String[] arr = str.split(split);
|
||||
final Integer[] ints = new Integer[arr.length];
|
||||
for (int i = 0; i < arr.length; i++)
|
||||
{
|
||||
final Integer v = toInt(arr[i], 0);
|
||||
ints[i] = v;
|
||||
}
|
||||
return ints;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Long数组<br>
|
||||
*
|
||||
* @param split 分隔符
|
||||
* @param str 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long[] toLongArray(String split, String str)
|
||||
{
|
||||
if (StringUtils.isEmpty(str))
|
||||
{
|
||||
return new Long[] {};
|
||||
}
|
||||
String[] arr = str.split(split);
|
||||
final Long[] longs = new Long[arr.length];
|
||||
for (int i = 0; i < arr.length; i++)
|
||||
{
|
||||
final Long v = toLong(arr[i], null);
|
||||
longs[i] = v;
|
||||
}
|
||||
return longs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为String数组<br>
|
||||
*
|
||||
* @param str 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String[] toStrArray(String str)
|
||||
{
|
||||
return toStrArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为String数组<br>
|
||||
*
|
||||
* @param split 分隔符
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String[] toStrArray(String split, String str)
|
||||
{
|
||||
return str.split(split);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为long<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long toLong(Object value, Long defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return (Long) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 支持科学计数法
|
||||
return new BigDecimal(valueStr.trim()).longValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为long<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long toLong(Object value)
|
||||
{
|
||||
return toLong(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为double<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Double toDouble(Object value, Double defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Double)
|
||||
{
|
||||
return (Double) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).doubleValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 支持科学计数法
|
||||
return new BigDecimal(valueStr.trim()).doubleValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为double<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Double toDouble(Object value)
|
||||
{
|
||||
return toDouble(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Float<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Float toFloat(Object value, Float defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Float)
|
||||
{
|
||||
return (Float) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).floatValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Float.parseFloat(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Float<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Float toFloat(Object value)
|
||||
{
|
||||
return toFloat(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为boolean<br>
|
||||
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Boolean toBool(Object value, Boolean defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Boolean)
|
||||
{
|
||||
return (Boolean) value;
|
||||
}
|
||||
String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
valueStr = valueStr.trim().toLowerCase();
|
||||
switch (valueStr)
|
||||
{
|
||||
case "true":
|
||||
return true;
|
||||
case "false":
|
||||
return false;
|
||||
case "yes":
|
||||
return true;
|
||||
case "ok":
|
||||
return true;
|
||||
case "no":
|
||||
return false;
|
||||
case "1":
|
||||
return true;
|
||||
case "0":
|
||||
return false;
|
||||
default:
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为boolean<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Boolean toBool(Object value)
|
||||
{
|
||||
return toBool(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Enum对象<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
*
|
||||
* @param clazz Enum的Class
|
||||
* @param value 值
|
||||
* @param defaultValue 默认值
|
||||
* @return Enum
|
||||
*/
|
||||
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (clazz.isAssignableFrom(value.getClass()))
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
E myE = (E) value;
|
||||
return myE;
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Enum.valueOf(clazz, valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Enum对象<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
*
|
||||
* @param clazz Enum的Class
|
||||
* @param value 值
|
||||
* @return Enum
|
||||
*/
|
||||
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value)
|
||||
{
|
||||
return toEnum(clazz, value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigInteger<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof BigInteger)
|
||||
{
|
||||
return (BigInteger) value;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return BigInteger.valueOf((Long) value);
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new BigInteger(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigInteger<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigInteger toBigInteger(Object value)
|
||||
{
|
||||
return toBigInteger(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigDecimal<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof BigDecimal)
|
||||
{
|
||||
return (BigDecimal) value;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return new BigDecimal((Long) value);
|
||||
}
|
||||
if (value instanceof Double)
|
||||
{
|
||||
return new BigDecimal((Double) value);
|
||||
}
|
||||
if (value instanceof Integer)
|
||||
{
|
||||
return new BigDecimal((Integer) value);
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new BigDecimal(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigDecimal<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Object value)
|
||||
{
|
||||
return toBigDecimal(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String utf8Str(Object obj)
|
||||
{
|
||||
return str(obj, CharsetKit.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param charsetName 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(Object obj, String charsetName)
|
||||
{
|
||||
return str(obj, Charset.forName(charsetName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param charset 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(Object obj, Charset charset)
|
||||
{
|
||||
if (null == obj)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (obj instanceof String)
|
||||
{
|
||||
return (String) obj;
|
||||
}
|
||||
else if (obj instanceof byte[] || obj instanceof Byte[])
|
||||
{
|
||||
return str((Byte[]) obj, charset);
|
||||
}
|
||||
else if (obj instanceof ByteBuffer)
|
||||
{
|
||||
return str((ByteBuffer) obj, charset);
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将byte数组转为字符串
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @param charset 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(byte[] bytes, String charset)
|
||||
{
|
||||
return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码字节码
|
||||
*
|
||||
* @param data 字符串
|
||||
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
|
||||
* @return 解码后的字符串
|
||||
*/
|
||||
public static String str(byte[] data, Charset charset)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null == charset)
|
||||
{
|
||||
return new String(data);
|
||||
}
|
||||
return new String(data, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将编码的byteBuffer数据转换为字符串
|
||||
*
|
||||
* @param data 数据
|
||||
* @param charset 字符集,如果为空使用当前系统字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(ByteBuffer data, String charset)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return str(data, Charset.forName(charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将编码的byteBuffer数据转换为字符串
|
||||
*
|
||||
* @param data 数据
|
||||
* @param charset 字符集,如果为空使用当前系统字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(ByteBuffer data, Charset charset)
|
||||
{
|
||||
if (null == charset)
|
||||
{
|
||||
charset = Charset.defaultCharset();
|
||||
}
|
||||
return charset.decode(data).toString();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- 全角半角转换
|
||||
/**
|
||||
* 半角转全角
|
||||
*
|
||||
* @param input String.
|
||||
* @return 全角字符串.
|
||||
*/
|
||||
public static String toSBC(String input)
|
||||
{
|
||||
return toSBC(input, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 半角转全角
|
||||
*
|
||||
* @param input String
|
||||
* @param notConvertSet 不替换的字符集合
|
||||
* @return 全角字符串.
|
||||
*/
|
||||
public static String toSBC(String input, Set<Character> notConvertSet)
|
||||
{
|
||||
char c[] = input.toCharArray();
|
||||
for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||
{
|
||||
// 跳过不替换的字符
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c[i] == ' ')
|
||||
{
|
||||
c[i] = '\u3000';
|
||||
}
|
||||
else if (c[i] < '\177')
|
||||
{
|
||||
c[i] = (char) (c[i] + 65248);
|
||||
|
||||
}
|
||||
}
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全角转半角
|
||||
*
|
||||
* @param input String.
|
||||
* @return 半角字符串
|
||||
*/
|
||||
public static String toDBC(String input)
|
||||
{
|
||||
return toDBC(input, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换全角为半角
|
||||
*
|
||||
* @param text 文本
|
||||
* @param notConvertSet 不替换的字符集合
|
||||
* @return 替换后的字符
|
||||
*/
|
||||
public static String toDBC(String text, Set<Character> notConvertSet)
|
||||
{
|
||||
char c[] = text.toCharArray();
|
||||
for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||
{
|
||||
// 跳过不替换的字符
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c[i] == '\u3000')
|
||||
{
|
||||
c[i] = ' ';
|
||||
}
|
||||
else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
|
||||
{
|
||||
c[i] = (char) (c[i] - 65248);
|
||||
}
|
||||
}
|
||||
String returnString = new String(c);
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
|
||||
*
|
||||
* @param n 数字
|
||||
* @return 中文大写数字
|
||||
*/
|
||||
public static String digitUppercase(double n)
|
||||
{
|
||||
String[] fraction = { "角", "分" };
|
||||
String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
|
||||
String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
|
||||
|
||||
String head = n < 0 ? "负" : "";
|
||||
n = Math.abs(n);
|
||||
|
||||
String s = "";
|
||||
for (int i = 0; i < fraction.length; i++)
|
||||
{
|
||||
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
}
|
||||
if (s.length() < 1)
|
||||
{
|
||||
s = "整";
|
||||
}
|
||||
int integerPart = (int) Math.floor(n);
|
||||
|
||||
for (int i = 0; i < unit[0].length && integerPart > 0; i++)
|
||||
{
|
||||
String p = "";
|
||||
for (int j = 0; j < unit[1].length && n > 0; j++)
|
||||
{
|
||||
p = digit[integerPart % 10] + unit[1][j] + p;
|
||||
integerPart = integerPart / 10;
|
||||
}
|
||||
s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
|
||||
}
|
||||
return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package com.ruoyi.common.utils.text;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符串格式化
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class StrFormatter
|
||||
{
|
||||
public static final String EMPTY_JSON = "{}";
|
||||
public static final char C_BACKSLASH = '\\';
|
||||
public static final char C_DELIM_START = '{';
|
||||
public static final char C_DELIM_END = '}';
|
||||
|
||||
/**
|
||||
* 格式化字符串<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param strPattern 字符串模板
|
||||
* @param argArray 参数列表
|
||||
* @return 结果
|
||||
*/
|
||||
public static String format(final String strPattern, final Object... argArray)
|
||||
{
|
||||
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
final int strPatternLength = strPattern.length();
|
||||
|
||||
// 初始化定义好的长度以获得更好的性能
|
||||
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
|
||||
|
||||
int handledPosition = 0;
|
||||
int delimIndex;// 占位符所在位置
|
||||
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
|
||||
{
|
||||
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
|
||||
if (delimIndex == -1)
|
||||
{
|
||||
if (handledPosition == 0)
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
else
|
||||
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
|
||||
sbuf.append(strPattern, handledPosition, strPatternLength);
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
|
||||
{
|
||||
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
|
||||
{
|
||||
// 转义符之前还有一个转义符,占位符依旧有效
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 占位符被转义
|
||||
argIndex--;
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(C_DELIM_START);
|
||||
handledPosition = delimIndex + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常占位符
|
||||
sbuf.append(strPattern, handledPosition, delimIndex);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append the characters following the last {} pair.
|
||||
// 加入最后一个占位符后所有的字符
|
||||
sbuf.append(strPattern, handledPosition, strPattern.length());
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
@ -7,8 +7,9 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.ruoyi.common.filter.RepeatableFilter;
|
||||
import com.ruoyi.common.filter.XssFilter;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.xss.XssFilter;
|
||||
|
||||
/**
|
||||
* Filter配置
|
||||
@ -36,11 +37,24 @@ public class FilterConfig
|
||||
registration.setFilter(new XssFilter());
|
||||
registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
|
||||
registration.setName("xssFilter");
|
||||
registration.setOrder(Integer.MAX_VALUE);
|
||||
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||
Map<String, String> initParameters = new HashMap<String, String>();
|
||||
initParameters.put("excludes", excludes);
|
||||
initParameters.put("enabled", enabled);
|
||||
registration.setInitParameters(initParameters);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Bean
|
||||
public FilterRegistrationBean someFilterRegistration()
|
||||
{
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(new RepeatableFilter());
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("repeatableFilter");
|
||||
registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
@ -93,6 +94,7 @@ public class MyBatisConfig
|
||||
{
|
||||
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
|
||||
String mapperLocations = env.getProperty("mybatis.mapperLocations");
|
||||
String configLocation = env.getProperty("mybatis.configLocation");
|
||||
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
|
||||
VFS.addImplClass(SpringBootVFS.class);
|
||||
|
||||
@ -100,6 +102,7 @@ public class MyBatisConfig
|
||||
sessionFactory.setDataSource(dataSource);
|
||||
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
|
||||
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
|
||||
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
|
||||
return sessionFactory.getObject();
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class ScheduleConfig
|
||||
{
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
{
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
|
||||
// quartz参数
|
||||
Properties prop = new Properties();
|
||||
prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
|
||||
prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// 线程池配置
|
||||
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// JobStore配置
|
||||
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
|
||||
// 集群配置
|
||||
prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
|
||||
// sqlserver 启用
|
||||
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
factory.setQuartzProperties(prop);
|
||||
|
||||
factory.setSchedulerName("RuoyiScheduler");
|
||||
// 延时启动
|
||||
factory.setStartupDelay(1);
|
||||
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// 可选,QuartzScheduler
|
||||
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
factory.setOverwriteExistingJobs(true);
|
||||
// 设置自动启动,默认为true
|
||||
factory.setAutoStartup(true);
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
@ -99,6 +99,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
||||
).permitAll()
|
||||
.antMatchers("/profile/**").anonymous()
|
||||
.antMatchers("/common/download**").anonymous()
|
||||
.antMatchers("/common/download/resource**").anonymous()
|
||||
.antMatchers("/swagger-ui.html").anonymous()
|
||||
.antMatchers("/swagger-resources/**").anonymous()
|
||||
.antMatchers("/webjars/**").anonymous()
|
||||
|
@ -2,14 +2,19 @@ package com.ruoyi.framework.interceptor.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.http.HttpHelper;
|
||||
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
|
||||
import com.ruoyi.framework.redis.RedisCache;
|
||||
|
||||
/**
|
||||
* 判断请求url和数据是否和上一次相同,
|
||||
* 判断请求url和数据是否和上一次相同,
|
||||
* 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
|
||||
*
|
||||
* @author ruoyi
|
||||
@ -21,7 +26,10 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||
|
||||
public final String REPEAT_TIME = "repeatTime";
|
||||
|
||||
public final String SESSION_REPEAT_KEY = "repeatData";
|
||||
public final String CACHE_REPEAT_KEY = "repeatData";
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 间隔时间,单位:秒 默认10秒
|
||||
@ -39,17 +47,22 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||
@Override
|
||||
public boolean isRepeatSubmit(HttpServletRequest request)
|
||||
{
|
||||
// 本次参数及系统时间
|
||||
String nowParams = JSONObject.toJSONString(request.getParameterMap());
|
||||
RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
|
||||
String nowParams = HttpHelper.getBodyString(repeatedlyRequest);
|
||||
|
||||
// body参数为空,获取Parameter的数据
|
||||
if (StringUtils.isEmpty(nowParams))
|
||||
{
|
||||
nowParams = JSONObject.toJSONString(request.getParameterMap());
|
||||
}
|
||||
Map<String, Object> nowDataMap = new HashMap<String, Object>();
|
||||
nowDataMap.put(REPEAT_PARAMS, nowParams);
|
||||
nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
|
||||
|
||||
// 请求地址(作为存放session的key值)
|
||||
// 请求地址(作为存放cache的key值)
|
||||
String url = request.getRequestURI();
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
Object sessionObj = session.getAttribute(SESSION_REPEAT_KEY);
|
||||
Object sessionObj = redisCache.getCacheObject(CACHE_REPEAT_KEY);
|
||||
if (sessionObj != null)
|
||||
{
|
||||
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
|
||||
@ -62,9 +75,9 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Object> sessionMap = new HashMap<String, Object>();
|
||||
sessionMap.put(url, nowDataMap);
|
||||
session.setAttribute(SESSION_REPEAT_KEY, sessionMap);
|
||||
Map<String, Object> cacheMap = new HashMap<String, Object>();
|
||||
cacheMap.put(url, nowDataMap);
|
||||
redisCache.setCacheObject(CACHE_REPEAT_KEY, cacheMap, intervalTime, TimeUnit.SECONDS);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -51,16 +51,16 @@ public class SysPermissionService
|
||||
*/
|
||||
public Set<String> getMenuPermission(SysUser user)
|
||||
{
|
||||
Set<String> roles = new HashSet<String>();
|
||||
Set<String> perms = new HashSet<String>();
|
||||
// 管理员拥有所有权限
|
||||
if (user.isAdmin())
|
||||
{
|
||||
roles.add("*:*:*");
|
||||
perms.add("*:*:*");
|
||||
}
|
||||
else
|
||||
{
|
||||
roles.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
|
||||
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
|
||||
}
|
||||
return roles;
|
||||
return perms;
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +77,7 @@ public class TokenService
|
||||
{
|
||||
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
|
||||
{
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
redisCache.setCacheObject(userKey, loginUser);
|
||||
refreshToken(loginUser);
|
||||
}
|
||||
}
|
||||
|
||||
|
28
ruoyi/src/main/java/com/ruoyi/framework/task/RyTask.java
Normal file
28
ruoyi/src/main/java/com/ruoyi/framework/task/RyTask.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.framework.task;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 定时任务调度测试
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component("ryTask")
|
||||
public class RyTask
|
||||
{
|
||||
public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
|
||||
{
|
||||
System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
|
||||
}
|
||||
|
||||
public void ryParams(String params)
|
||||
{
|
||||
System.out.println("执行有参方法:" + params);
|
||||
}
|
||||
|
||||
public void ryNoParams()
|
||||
{
|
||||
System.out.println("执行无参方法");
|
||||
}
|
||||
}
|
@ -28,7 +28,6 @@ import oshi.util.Util;
|
||||
*/
|
||||
public class Server
|
||||
{
|
||||
|
||||
private static final int OSHI_WAIT_SECOND = 1000;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,79 @@
|
||||
package com.ruoyi.framework.web.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tree基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TreeEntity extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 父菜单名称 */
|
||||
private String parentName;
|
||||
|
||||
/** 父菜单ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 显示顺序 */
|
||||
private Integer orderNum;
|
||||
|
||||
/** 祖级列表 */
|
||||
private String ancestors;
|
||||
|
||||
/** 子部门 */
|
||||
private List<?> children = new ArrayList<>();
|
||||
|
||||
public String getParentName()
|
||||
{
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName)
|
||||
{
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public Long getParentId()
|
||||
{
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId)
|
||||
{
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public Integer getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public void setOrderNum(Integer orderNum)
|
||||
{
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
public String getAncestors()
|
||||
{
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
public void setAncestors(String ancestors)
|
||||
{
|
||||
this.ancestors = ancestors;
|
||||
}
|
||||
|
||||
public List<?> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<?> children)
|
||||
{
|
||||
this.children = children;
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
@ -86,4 +87,23 @@ public class CommonController
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地资源通用下载
|
||||
*/
|
||||
@GetMapping("/common/download/resource")
|
||||
public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception
|
||||
{
|
||||
// 本地资源路径
|
||||
String localPath = RuoYiConfig.getProfile();
|
||||
// 数据库资源地址
|
||||
String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
|
||||
// 下载名称
|
||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("multipart/form-data");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
|
||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,130 @@
|
||||
package com.ruoyi.project.monitor.controller;
|
||||
|
||||
import java.util.List;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
||||
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
|
||||
import com.ruoyi.framework.web.controller.BaseController;
|
||||
import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
import com.ruoyi.project.monitor.service.ISysJobService;
|
||||
|
||||
/**
|
||||
* 调度任务信息操作处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/job")
|
||||
public class SysJobController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysJobService jobService;
|
||||
|
||||
/**
|
||||
* 查询定时任务列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysJob sysJob)
|
||||
{
|
||||
startPage();
|
||||
List<SysJob> list = jobService.selectJobList(sysJob);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出定时任务列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.EXPORT)
|
||||
@GetMapping("/export")
|
||||
public AjaxResult export(SysJob sysJob)
|
||||
{
|
||||
List<SysJob> list = jobService.selectJobList(sysJob);
|
||||
ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
|
||||
return util.exportExcel(list, "定时任务");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
|
||||
@GetMapping(value = "/{jobId}")
|
||||
public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
|
||||
{
|
||||
return AjaxResult.success(jobService.selectJobById(jobId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增定时任务
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:add')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
|
||||
{
|
||||
return toAjax(jobService.insertJob(sysJob));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改定时任务
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:edit')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
|
||||
{
|
||||
return toAjax(jobService.updateJob(sysJob));
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务状态修改
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException
|
||||
{
|
||||
SysJob newJob = jobService.selectJobById(job.getJobId());
|
||||
newJob.setStatus(job.getStatus());
|
||||
return toAjax(jobService.changeStatus(newJob));
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务立即执行一次
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/run")
|
||||
public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
|
||||
{
|
||||
jobService.run(job);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
|
||||
@Log(title = "定时任务", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{jobIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
|
||||
{
|
||||
jobService.deleteJobByIds(jobIds);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.ruoyi.project.monitor.controller;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
||||
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
|
||||
import com.ruoyi.project.monitor.domain.SysJobLog;
|
||||
import com.ruoyi.project.monitor.service.ISysJobLogService;
|
||||
import com.ruoyi.framework.web.controller.BaseController;
|
||||
import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 调度日志操作处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/jobLog")
|
||||
public class SysJobLogController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysJobLogService jobLogService;
|
||||
|
||||
/**
|
||||
* 查询定时任务调度日志列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysJobLog sysJobLog)
|
||||
{
|
||||
startPage();
|
||||
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出定时任务调度日志列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
|
||||
@Log(title = "任务调度日志", businessType = BusinessType.EXPORT)
|
||||
@GetMapping("/export")
|
||||
public AjaxResult export(SysJobLog sysJobLog)
|
||||
{
|
||||
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
|
||||
ExcelUtil<SysJobLog> util = new ExcelUtil<SysJobLog>(SysJobLog.class);
|
||||
return util.exportExcel(list, "调度日志");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据调度编号获取详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
|
||||
@GetMapping(value = "/{configId}")
|
||||
public AjaxResult getInfo(@PathVariable Long jobLogId)
|
||||
{
|
||||
return AjaxResult.success(jobLogService.selectJobLogById(jobLogId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除定时任务调度日志
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
|
||||
@Log(title = "定时任务调度日志", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{jobLogIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] jobLogIds)
|
||||
{
|
||||
return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
|
||||
@Log(title = "调度日志", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/clean")
|
||||
public AjaxResult clean()
|
||||
{
|
||||
jobLogService.cleanJobLog();
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
170
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJob.java
Normal file
170
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysJob.java
Normal file
@ -0,0 +1,170 @@
|
||||
package com.ruoyi.project.monitor.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.job.CronUtils;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.framework.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 定时任务调度表 sys_job
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysJob extends BaseEntity implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 任务ID */
|
||||
@Excel(name = "任务序号", cellType = ColumnType.NUMERIC)
|
||||
private Long jobId;
|
||||
|
||||
/** 任务名称 */
|
||||
@Excel(name = "任务名称")
|
||||
private String jobName;
|
||||
|
||||
/** 任务组名 */
|
||||
@Excel(name = "任务组名")
|
||||
private String jobGroup;
|
||||
|
||||
/** 调用目标字符串 */
|
||||
@Excel(name = "调用目标字符串")
|
||||
private String invokeTarget;
|
||||
|
||||
/** cron执行表达式 */
|
||||
@Excel(name = "执行表达式 ")
|
||||
private String cronExpression;
|
||||
|
||||
/** cron计划策略 */
|
||||
@Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行")
|
||||
private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
|
||||
|
||||
/** 是否并发执行(0允许 1禁止) */
|
||||
@Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止")
|
||||
private String concurrent;
|
||||
|
||||
/** 任务状态(0正常 1暂停) */
|
||||
@Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
|
||||
private String status;
|
||||
|
||||
public Long getJobId()
|
||||
{
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public void setJobId(Long jobId)
|
||||
{
|
||||
this.jobId = jobId;
|
||||
}
|
||||
|
||||
@NotBlank(message = "任务名称不能为空")
|
||||
@Size(min = 0, max = 64, message = "任务名称不能超过64个字符")
|
||||
public String getJobName()
|
||||
{
|
||||
return jobName;
|
||||
}
|
||||
|
||||
public void setJobName(String jobName)
|
||||
{
|
||||
this.jobName = jobName;
|
||||
}
|
||||
|
||||
public String getJobGroup()
|
||||
{
|
||||
return jobGroup;
|
||||
}
|
||||
|
||||
public void setJobGroup(String jobGroup)
|
||||
{
|
||||
this.jobGroup = jobGroup;
|
||||
}
|
||||
|
||||
@NotBlank(message = "调用目标字符串不能为空")
|
||||
@Size(min = 0, max = 1000, message = "调用目标字符串长度不能超过500个字符")
|
||||
public String getInvokeTarget()
|
||||
{
|
||||
return invokeTarget;
|
||||
}
|
||||
|
||||
public void setInvokeTarget(String invokeTarget)
|
||||
{
|
||||
this.invokeTarget = invokeTarget;
|
||||
}
|
||||
|
||||
@NotBlank(message = "Cron执行表达式不能为空")
|
||||
@Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符")
|
||||
public String getCronExpression()
|
||||
{
|
||||
return cronExpression;
|
||||
}
|
||||
|
||||
public void setCronExpression(String cronExpression)
|
||||
{
|
||||
this.cronExpression = cronExpression;
|
||||
}
|
||||
|
||||
public Date getNextValidTime()
|
||||
{
|
||||
if (StringUtils.isNotEmpty(cronExpression))
|
||||
{
|
||||
return CronUtils.getNextExecution(cronExpression);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getMisfirePolicy()
|
||||
{
|
||||
return misfirePolicy;
|
||||
}
|
||||
|
||||
public void setMisfirePolicy(String misfirePolicy)
|
||||
{
|
||||
this.misfirePolicy = misfirePolicy;
|
||||
}
|
||||
|
||||
public String getConcurrent()
|
||||
{
|
||||
return concurrent;
|
||||
}
|
||||
|
||||
public void setConcurrent(String concurrent)
|
||||
{
|
||||
this.concurrent = concurrent;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("jobId", getJobId())
|
||||
.append("jobName", getJobName())
|
||||
.append("jobGroup", getJobGroup())
|
||||
.append("cronExpression", getCronExpression())
|
||||
.append("nextValidTime", getNextValidTime())
|
||||
.append("misfirePolicy", getMisfirePolicy())
|
||||
.append("concurrent", getConcurrent())
|
||||
.append("status", getStatus())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.ruoyi.project.monitor.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
|
||||
import com.ruoyi.framework.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志表 sys_job_log
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysJobLog extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** ID */
|
||||
@Excel(name = "日志序号")
|
||||
private Long jobLogId;
|
||||
|
||||
/** 任务名称 */
|
||||
@Excel(name = "任务名称")
|
||||
private String jobName;
|
||||
|
||||
/** 任务组名 */
|
||||
@Excel(name = "任务组名")
|
||||
private String jobGroup;
|
||||
|
||||
/** 调用目标字符串 */
|
||||
@Excel(name = "调用目标字符串")
|
||||
private String invokeTarget;
|
||||
|
||||
/** 日志信息 */
|
||||
@Excel(name = "日志信息")
|
||||
private String jobMessage;
|
||||
|
||||
/** 执行状态(0正常 1失败) */
|
||||
@Excel(name = "执行状态", readConverterExp = "0=正常,1=失败")
|
||||
private String status;
|
||||
|
||||
/** 异常信息 */
|
||||
@Excel(name = "异常信息")
|
||||
private String exceptionInfo;
|
||||
|
||||
/** 开始时间 */
|
||||
private Date startTime;
|
||||
|
||||
/** 停止时间 */
|
||||
private Date stopTime;
|
||||
|
||||
public Long getJobLogId()
|
||||
{
|
||||
return jobLogId;
|
||||
}
|
||||
|
||||
public void setJobLogId(Long jobLogId)
|
||||
{
|
||||
this.jobLogId = jobLogId;
|
||||
}
|
||||
|
||||
public String getJobName()
|
||||
{
|
||||
return jobName;
|
||||
}
|
||||
|
||||
public void setJobName(String jobName)
|
||||
{
|
||||
this.jobName = jobName;
|
||||
}
|
||||
|
||||
public String getJobGroup()
|
||||
{
|
||||
return jobGroup;
|
||||
}
|
||||
|
||||
public void setJobGroup(String jobGroup)
|
||||
{
|
||||
this.jobGroup = jobGroup;
|
||||
}
|
||||
|
||||
public String getInvokeTarget()
|
||||
{
|
||||
return invokeTarget;
|
||||
}
|
||||
|
||||
public void setInvokeTarget(String invokeTarget)
|
||||
{
|
||||
this.invokeTarget = invokeTarget;
|
||||
}
|
||||
|
||||
public String getJobMessage()
|
||||
{
|
||||
return jobMessage;
|
||||
}
|
||||
|
||||
public void setJobMessage(String jobMessage)
|
||||
{
|
||||
this.jobMessage = jobMessage;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getExceptionInfo()
|
||||
{
|
||||
return exceptionInfo;
|
||||
}
|
||||
|
||||
public void setExceptionInfo(String exceptionInfo)
|
||||
{
|
||||
this.exceptionInfo = exceptionInfo;
|
||||
}
|
||||
|
||||
public Date getStartTime()
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Date startTime)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public Date getStopTime()
|
||||
{
|
||||
return stopTime;
|
||||
}
|
||||
|
||||
public void setStopTime(Date stopTime)
|
||||
{
|
||||
this.stopTime = stopTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("jobLogId", getJobLogId())
|
||||
.append("jobName", getJobName())
|
||||
.append("jobGroup", getJobGroup())
|
||||
.append("jobMessage", getJobMessage())
|
||||
.append("status", getStatus())
|
||||
.append("exceptionInfo", getExceptionInfo())
|
||||
.append("startTime", getStartTime())
|
||||
.append("stopTime", getStopTime())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.project.monitor.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.project.monitor.domain.SysJobLog;
|
||||
|
||||
/**
|
||||
* 调度任务日志信息 数据层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface SysJobLogMapper
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 查询所有调度任务日志
|
||||
*
|
||||
* @return 调度任务日志列表
|
||||
*/
|
||||
public List<SysJobLog> selectJobLogAll();
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobLogId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
public SysJobLog selectJobLogById(Long jobLogId);
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJobLog(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param logIds 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogByIds(Long[] logIds);
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogById(Long jobId);
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
public void cleanJobLog();
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.ruoyi.project.monitor.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 调度任务信息 数据层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface SysJobMapper
|
||||
{
|
||||
/**
|
||||
* 查询调度任务日志集合
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 操作日志集合
|
||||
*/
|
||||
public List<SysJob> selectJobList(SysJob job);
|
||||
|
||||
/**
|
||||
* 查询所有调度任务
|
||||
*
|
||||
* @return 调度任务列表
|
||||
*/
|
||||
public List<SysJob> selectJobAll();
|
||||
|
||||
/**
|
||||
* 通过调度ID查询调度任务信息
|
||||
*
|
||||
* @param jobId 调度ID
|
||||
* @return 角色对象信息
|
||||
*/
|
||||
public SysJob selectJobById(Long jobId);
|
||||
|
||||
/**
|
||||
* 通过调度ID删除调度任务信息
|
||||
*
|
||||
* @param jobId 调度ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobById(Long jobId);
|
||||
|
||||
/**
|
||||
* 批量删除调度任务信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 修改调度任务信息
|
||||
*
|
||||
* @param job 调度任务信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateJob(SysJob job);
|
||||
|
||||
/**
|
||||
* 新增调度任务信息
|
||||
*
|
||||
* @param job 调度任务信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJob(SysJob job);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.ruoyi.project.monitor.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.project.monitor.domain.SysJobLog;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志信息信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysJobLogService
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobLogId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
public SysJobLog selectJobLogById(Long jobLogId);
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
*/
|
||||
public void addJobLog(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param logIds 需要删除的日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogByIds(Long[] logIds);
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogById(Long jobId);
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
public void cleanJobLog();
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.ruoyi.project.monitor.service;
|
||||
|
||||
import java.util.List;
|
||||
import org.quartz.SchedulerException;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务调度信息信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysJobService
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器的计划任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 调度任务集合
|
||||
*/
|
||||
public List<SysJob> selectJobList(SysJob job);
|
||||
|
||||
/**
|
||||
* 通过调度任务ID查询调度信息
|
||||
*
|
||||
* @param jobId 调度任务ID
|
||||
* @return 调度任务对象信息
|
||||
*/
|
||||
public SysJob selectJobById(Long jobId);
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int pauseJob(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int resumeJob(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 删除任务后,所对应的trigger也将被删除
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJob(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 批量删除调度信息
|
||||
*
|
||||
* @param jobIds 需要删除的任务ID
|
||||
* @return 结果
|
||||
*/
|
||||
public void deleteJobByIds(Long[] jobIds) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 任务调度状态修改
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int changeStatus(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 立即运行任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public void run(SysJob job) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 新增任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJob(SysJob job) throws SchedulerException, TaskException;
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateJob(SysJob job) throws SchedulerException, TaskException;
|
||||
|
||||
/**
|
||||
* 校验cron表达式是否有效
|
||||
*
|
||||
* @param cronExpression 表达式
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean checkCronExpressionIsValid(String cronExpression);
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.ruoyi.project.monitor.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.project.monitor.domain.SysJobLog;
|
||||
import com.ruoyi.project.monitor.mapper.SysJobLogMapper;
|
||||
import com.ruoyi.project.monitor.service.ISysJobLogService;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class SysJobLogServiceImpl implements ISysJobLogService
|
||||
{
|
||||
@Autowired
|
||||
private SysJobLogMapper jobLogMapper;
|
||||
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog)
|
||||
{
|
||||
return jobLogMapper.selectJobLogList(jobLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobLogId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysJobLog selectJobLogById(Long jobLogId)
|
||||
{
|
||||
return jobLogMapper.selectJobLogById(jobLogId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
*/
|
||||
@Override
|
||||
public void addJobLog(SysJobLog jobLog)
|
||||
{
|
||||
jobLogMapper.insertJobLog(jobLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param logIds 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteJobLogByIds(Long[] logIds)
|
||||
{
|
||||
return jobLogMapper.deleteJobLogByIds(logIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
*/
|
||||
@Override
|
||||
public int deleteJobLogById(Long jobId)
|
||||
{
|
||||
return jobLogMapper.deleteJobLogById(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
@Override
|
||||
public void cleanJobLog()
|
||||
{
|
||||
jobLogMapper.cleanJobLog();
|
||||
}
|
||||
}
|
@ -0,0 +1,254 @@
|
||||
package com.ruoyi.project.monitor.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.common.utils.job.CronUtils;
|
||||
import com.ruoyi.common.utils.job.ScheduleUtils;
|
||||
import com.ruoyi.project.monitor.domain.SysJob;
|
||||
import com.ruoyi.project.monitor.mapper.SysJobMapper;
|
||||
import com.ruoyi.project.monitor.service.ISysJobService;
|
||||
|
||||
/**
|
||||
* 定时任务调度信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class SysJobServiceImpl implements ISysJobService
|
||||
{
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
private SysJobMapper jobMapper;
|
||||
|
||||
/**
|
||||
* 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据)
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() throws SchedulerException, TaskException
|
||||
{
|
||||
scheduler.clear();
|
||||
List<SysJob> jobList = jobMapper.selectJobAll();
|
||||
for (SysJob job : jobList)
|
||||
{
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取quartz调度器的计划任务列表
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysJob> selectJobList(SysJob job)
|
||||
{
|
||||
return jobMapper.selectJobList(job);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过调度任务ID查询调度信息
|
||||
*
|
||||
* @param jobId 调度任务ID
|
||||
* @return 调度任务对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysJob selectJobById(Long jobId)
|
||||
{
|
||||
return jobMapper.selectJobById(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int pauseJob(SysJob job) throws SchedulerException
|
||||
{
|
||||
Long jobId = job.getJobId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int resumeJob(SysJob job) throws SchedulerException
|
||||
{
|
||||
Long jobId = job.getJobId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务后,所对应的trigger也将被删除
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int deleteJob(SysJob job) throws SchedulerException
|
||||
{
|
||||
Long jobId = job.getJobId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
int rows = jobMapper.deleteJobById(jobId);
|
||||
if (rows > 0)
|
||||
{
|
||||
scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除调度信息
|
||||
*
|
||||
* @param jobIds 需要删除的任务ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteJobByIds(Long[] jobIds) throws SchedulerException
|
||||
{
|
||||
for (Long jobId : jobIds)
|
||||
{
|
||||
SysJob job = jobMapper.selectJobById(jobId);
|
||||
deleteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务调度状态修改
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int changeStatus(SysJob job) throws SchedulerException
|
||||
{
|
||||
int rows = 0;
|
||||
String status = job.getStatus();
|
||||
if (ScheduleConstants.Status.NORMAL.getValue().equals(status))
|
||||
{
|
||||
rows = resumeJob(job);
|
||||
}
|
||||
else if (ScheduleConstants.Status.PAUSE.getValue().equals(status))
|
||||
{
|
||||
rows = pauseJob(job);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即运行任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(SysJob job) throws SchedulerException
|
||||
{
|
||||
Long jobId = job.getJobId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
SysJob properties = selectJobById(job.getJobId());
|
||||
// 参数
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
|
||||
scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增任务
|
||||
*
|
||||
* @param job 调度信息 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int insertJob(SysJob job) throws SchedulerException, TaskException
|
||||
{
|
||||
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
|
||||
int rows = jobMapper.insertJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务的时间表达式
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int updateJob(SysJob job) throws SchedulerException, TaskException
|
||||
{
|
||||
SysJob properties = selectJobById(job.getJobId());
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
updateSchedulerJob(job, properties.getJobGroup());
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
*
|
||||
* @param job 任务对象
|
||||
* @param jobGroup 任务组名
|
||||
*/
|
||||
public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException
|
||||
{
|
||||
Long jobId = job.getJobId();
|
||||
// 判断是否存在
|
||||
JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
|
||||
if (scheduler.checkExists(jobKey))
|
||||
{
|
||||
// 防止创建时存在数据问题 先移除,然后在执行创建操作
|
||||
scheduler.deleteJob(jobKey);
|
||||
}
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验cron表达式是否有效
|
||||
*
|
||||
* @param cronExpression 表达式
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkCronExpressionIsValid(String cronExpression)
|
||||
{
|
||||
return CronUtils.isValid(cronExpression);
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ public class SysDeptController extends BaseController
|
||||
public AjaxResult list(SysDept dept)
|
||||
{
|
||||
List<SysDept> depts = deptService.selectDeptList(dept);
|
||||
return AjaxResult.success(deptService.buildDeptTree(depts));
|
||||
return AjaxResult.success(depts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@ public class SysMenuController extends BaseController
|
||||
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
||||
Long userId = loginUser.getUser().getUserId();
|
||||
List<SysMenu> menus = menuService.selectMenuList(menu, userId);
|
||||
return AjaxResult.success(menuService.buildMenuTree(menus));
|
||||
return AjaxResult.success(menus);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,9 +84,9 @@ public class SysNoticeController extends BaseController
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
|
||||
@Log(title = "通知公告", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{noticeId}")
|
||||
public AjaxResult remove(@PathVariable Long noticeId)
|
||||
@DeleteMapping("/{noticeIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] noticeIds)
|
||||
{
|
||||
return toAjax(noticeService.deleteNoticeById(noticeId));
|
||||
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
|
||||
}
|
||||
}
|
||||
|
@ -56,5 +56,5 @@ public interface SysNoticeMapper
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeByIds(Long noticeIds);
|
||||
public int deleteNoticeByIds(Long[] noticeIds);
|
||||
}
|
@ -56,5 +56,5 @@ public interface ISysNoticeService
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeByIds(Long noticeIds);
|
||||
public int deleteNoticeByIds(Long[] noticeIds);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
|
||||
* @param noticeIds 需要删除的公告ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeByIds(Long noticeIds)
|
||||
public int deleteNoticeByIds(Long[] noticeIds)
|
||||
{
|
||||
return noticeMapper.deleteNoticeByIds(noticeIds);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.utils.text.Convert;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
||||
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
|
||||
import com.ruoyi.framework.web.controller.BaseController;
|
||||
@ -37,7 +37,6 @@ import com.ruoyi.project.tool.gen.service.IGenTableService;
|
||||
@RequestMapping("/tool/gen")
|
||||
public class GenController extends BaseController
|
||||
{
|
||||
|
||||
@Autowired
|
||||
private IGenTableService genTableService;
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.ruoyi.project.tool.gen.domain;
|
||||
import java.util.List;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import com.ruoyi.common.constant.GenConstants;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.web.domain.BaseEntity;
|
||||
@ -262,7 +263,8 @@ public class GenTable extends BaseEntity
|
||||
{
|
||||
if (isTree(tplCategory))
|
||||
{
|
||||
StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.TREE_ENTITY);
|
||||
return StringUtils.equalsAnyIgnoreCase(javaField,
|
||||
ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY));
|
||||
}
|
||||
return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package com.ruoyi.project.tool.gen.service;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.utils.text.Convert;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.project.tool.gen.domain.GenTableColumn;
|
||||
import com.ruoyi.project.tool.gen.mapper.GenTableColumnMapper;
|
||||
|
||||
|
@ -166,12 +166,32 @@ public class GenUtils
|
||||
if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix))
|
||||
{
|
||||
String[] searchList = StringUtils.split(tablePrefix, ",");
|
||||
String[] replacementList = emptyList(searchList.length);
|
||||
tableName = StringUtils.replaceEach(tableName, searchList, replacementList);
|
||||
tableName = replaceFirst(tableName, searchList);
|
||||
}
|
||||
return StringUtils.convertToCamelCase(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量替换前缀
|
||||
*
|
||||
* @param replacementm 替换值
|
||||
* @param searchList 替换列表
|
||||
* @return
|
||||
*/
|
||||
public static String replaceFirst(String replacementm, String[] searchList)
|
||||
{
|
||||
String text = replacementm;
|
||||
for (String searchString : searchList)
|
||||
{
|
||||
if (replacementm.startsWith(searchString))
|
||||
{
|
||||
text = replacementm.replaceFirst(searchString, "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关键字替换
|
||||
*
|
||||
@ -219,20 +239,4 @@ public class GenUtils
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取空数组列表
|
||||
*
|
||||
* @param length 长度
|
||||
* @return 数组信息
|
||||
*/
|
||||
public static String[] emptyList(int length)
|
||||
{
|
||||
String[] values = new String[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
values[i] = StringUtils.EMPTY;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
@ -95,7 +95,14 @@ public class VelocityUtils
|
||||
templates.add("vm/xml/mapper.xml.vm");
|
||||
templates.add("vm/sql/sql.vm");
|
||||
templates.add("vm/js/api.js.vm");
|
||||
templates.add("vm/vue/index.vue.vm");
|
||||
if (GenConstants.TPL_CRUD.equals(tplCategory))
|
||||
{
|
||||
templates.add("vm/vue/index.vue.vm");
|
||||
}
|
||||
else if (GenConstants.TPL_TREE.equals(tplCategory))
|
||||
{
|
||||
templates.add("vm/vue/index-tree.vue.vm");
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
@ -147,11 +154,15 @@ public class VelocityUtils
|
||||
{
|
||||
fileName = businessName + "Menu.sql";
|
||||
}
|
||||
else if (template.contains("js.vm"))
|
||||
else if (template.contains("api.js.vm"))
|
||||
{
|
||||
fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
|
||||
}
|
||||
else if (template.contains("vue.vm"))
|
||||
else if (template.contains("index.vue.vm"))
|
||||
{
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
|
||||
}
|
||||
else if (template.contains("index-tree.vue.vm"))
|
||||
{
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 2.0.0
|
||||
version: 2.2.0
|
||||
# 版权年份
|
||||
copyrightYear: 2019
|
||||
# 实例演示开关
|
||||
@ -28,7 +28,6 @@ server:
|
||||
# Tomcat启动初始化的线程数,默认值25
|
||||
min-spare-threads: 30
|
||||
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
|
@ -40,6 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
and date_format(login_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
||||
</if>
|
||||
</where>
|
||||
order by info_id desc
|
||||
</select>
|
||||
|
||||
<delete id="deleteLogininforByIds" parameterType="Long">
|
||||
|
@ -39,7 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="title != null and title != ''">
|
||||
AND title like concat('%', #{title}, '%')
|
||||
</if>
|
||||
<if test="businessType != null">
|
||||
<if test="businessType != null and businessType != ''">
|
||||
AND business_type = #{businessType}
|
||||
</if>
|
||||
<if test="businessTypes != null and businessTypes.length > 0">
|
||||
@ -61,6 +61,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
and date_format(oper_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
||||
</if>
|
||||
</where>
|
||||
order by oper_id desc
|
||||
</select>
|
||||
|
||||
<delete id="deleteOperLogByIds" parameterType="Long">
|
||||
|
93
ruoyi/src/main/resources/mybatis/system/SysJobLogMapper.xml
Normal file
93
ruoyi/src/main/resources/mybatis/system/SysJobLogMapper.xml
Normal file
@ -0,0 +1,93 @@
|
||||
<?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="com.ruoyi.project.monitor.mapper.SysJobLogMapper">
|
||||
|
||||
<resultMap type="SysJobLog" id="SysJobLogResult">
|
||||
<id property="jobLogId" column="job_log_id" />
|
||||
<result property="jobName" column="job_name" />
|
||||
<result property="jobGroup" column="job_group" />
|
||||
<result property="invokeTarget" column="invoke_target" />
|
||||
<result property="jobMessage" column="job_message" />
|
||||
<result property="status" column="status" />
|
||||
<result property="exceptionInfo" column="exception_info" />
|
||||
<result property="createTime" column="create_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectJobLogVo">
|
||||
select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time
|
||||
from sys_job_log
|
||||
</sql>
|
||||
|
||||
<select id="selectJobLogList" parameterType="SysJobLog" resultMap="SysJobLogResult">
|
||||
<include refid="selectJobLogVo"/>
|
||||
<where>
|
||||
<if test="jobName != null and jobName != ''">
|
||||
AND job_name like concat('%', #{jobName}, '%')
|
||||
</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">
|
||||
AND job_group = #{jobGroup}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">
|
||||
AND invoke_target like concat('%', #{invokeTarget}, '%')
|
||||
</if>
|
||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
||||
and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
||||
</if>
|
||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
||||
and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectJobLogAll" resultMap="SysJobLogResult">
|
||||
<include refid="selectJobLogVo"/>
|
||||
</select>
|
||||
|
||||
<select id="selectJobLogById" parameterType="Long" resultMap="SysJobLogResult">
|
||||
<include refid="selectJobLogVo"/>
|
||||
where job_log_id = #{jobLogId}
|
||||
</select>
|
||||
|
||||
<delete id="deleteJobLogById" parameterType="Long">
|
||||
delete from sys_job_log where job_log_id = #{jobLogId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteJobLogByIds" parameterType="Long">
|
||||
delete from sys_job_log where job_log_id in
|
||||
<foreach collection="array" item="jobLogId" open="(" separator="," close=")">
|
||||
#{jobLogId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="cleanJobLog">
|
||||
truncate table sys_job_log
|
||||
</update>
|
||||
|
||||
<insert id="insertJobLog" parameterType="SysJobLog">
|
||||
insert into sys_job_log(
|
||||
<if test="jobLogId != null and jobLogId != 0">job_log_id,</if>
|
||||
<if test="jobName != null and jobName != ''">job_name,</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">job_group,</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if>
|
||||
<if test="jobMessage != null and jobMessage != ''">job_message,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="exceptionInfo != null and exceptionInfo != ''">exception_info,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="jobLogId != null and jobLogId != 0">#{jobLogId},</if>
|
||||
<if test="jobName != null and jobName != ''">#{jobName},</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if>
|
||||
<if test="jobMessage != null and jobMessage != ''">#{jobMessage},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="exceptionInfo != null and exceptionInfo != ''">#{exceptionInfo},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
</mapper>
|
111
ruoyi/src/main/resources/mybatis/system/SysJobMapper.xml
Normal file
111
ruoyi/src/main/resources/mybatis/system/SysJobMapper.xml
Normal file
@ -0,0 +1,111 @@
|
||||
<?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="com.ruoyi.project.monitor.mapper.SysJobMapper">
|
||||
|
||||
<resultMap type="SysJob" id="SysJobResult">
|
||||
<id property="jobId" column="job_id" />
|
||||
<result property="jobName" column="job_name" />
|
||||
<result property="jobGroup" column="job_group" />
|
||||
<result property="invokeTarget" column="invoke_target" />
|
||||
<result property="cronExpression" column="cron_expression" />
|
||||
<result property="misfirePolicy" column="misfire_policy" />
|
||||
<result property="concurrent" column="concurrent" />
|
||||
<result property="status" column="status" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectJobVo">
|
||||
select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark
|
||||
from sys_job
|
||||
</sql>
|
||||
|
||||
<select id="selectJobList" parameterType="SysJob" resultMap="SysJobResult">
|
||||
<include refid="selectJobVo"/>
|
||||
<where>
|
||||
<if test="jobName != null and jobName != ''">
|
||||
AND job_name like concat('%', #{jobName}, '%')
|
||||
</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">
|
||||
AND job_group = #{jobGroup}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">
|
||||
AND invoke_target like concat('%', #{invokeTarget}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectJobAll" resultMap="SysJobResult">
|
||||
<include refid="selectJobVo"/>
|
||||
</select>
|
||||
|
||||
<select id="selectJobById" parameterType="Long" resultMap="SysJobResult">
|
||||
<include refid="selectJobVo"/>
|
||||
where job_id = #{jobId}
|
||||
</select>
|
||||
|
||||
<delete id="deleteJobById" parameterType="Long">
|
||||
delete from sys_job where job_id = #{jobId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteJobByIds" parameterType="Long">
|
||||
delete from sys_job where job_id in
|
||||
<foreach collection="array" item="jobId" open="(" separator="," close=")">
|
||||
#{jobId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="updateJob" parameterType="SysJob">
|
||||
update sys_job
|
||||
<set>
|
||||
<if test="jobName != null and jobName != ''">job_name = #{jobName},</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">job_group = #{jobGroup},</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">invoke_target = #{invokeTarget},</if>
|
||||
<if test="cronExpression != null and cronExpression != ''">cron_expression = #{cronExpression},</if>
|
||||
<if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy = #{misfirePolicy},</if>
|
||||
<if test="concurrent != null and concurrent != ''">concurrent = #{concurrent},</if>
|
||||
<if test="status !=null">status = #{status},</if>
|
||||
<if test="remark != null and remark != ''">remark = #{remark},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where job_id = #{jobId}
|
||||
</update>
|
||||
|
||||
<insert id="insertJob" parameterType="SysJob" useGeneratedKeys="true" keyProperty="jobId">
|
||||
insert into sys_job(
|
||||
<if test="jobId != null and jobId != 0">job_id,</if>
|
||||
<if test="jobName != null and jobName != ''">job_name,</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">job_group,</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if>
|
||||
<if test="cronExpression != null and cronExpression != ''">cron_expression,</if>
|
||||
<if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy,</if>
|
||||
<if test="concurrent != null and concurrent != ''">concurrent,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="remark != null and remark != ''">remark,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="jobId != null and jobId != 0">#{jobId},</if>
|
||||
<if test="jobName != null and jobName != ''">#{jobName},</if>
|
||||
<if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if>
|
||||
<if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if>
|
||||
<if test="cronExpression != null and cronExpression != ''">#{cronExpression},</if>
|
||||
<if test="misfirePolicy != null and misfirePolicy != ''">#{misfirePolicy},</if>
|
||||
<if test="concurrent != null and concurrent != ''">#{concurrent},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="remark != null and remark != ''">#{remark},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
</mapper>
|
@ -18,7 +18,10 @@ import ${packageName}.service.I${ClassName}Service;
|
||||
import com.ruoyi.framework.web.controller.BaseController;
|
||||
import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
#if($table.crud)
|
||||
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||
#elseif($table.tree)
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${functionName}Controller
|
||||
@ -38,12 +41,20 @@ public class ${ClassName}Controller extends BaseController
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
|
||||
@GetMapping("/list")
|
||||
#if($table.crud)
|
||||
public TableDataInfo list(${ClassName} ${className})
|
||||
{
|
||||
startPage();
|
||||
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
|
||||
return getDataTable(list);
|
||||
}
|
||||
#elseif($table.tree)
|
||||
public AjaxResult list(${ClassName} ${className})
|
||||
{
|
||||
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* 导出${functionName}列表
|
||||
|
@ -3,7 +3,11 @@ package ${packageName}.domain;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
|
||||
#if($table.crud)
|
||||
import com.ruoyi.framework.web.domain.BaseEntity;
|
||||
#elseif($table.tree)
|
||||
import com.ruoyi.framework.web.domain.TreeEntity;
|
||||
#end
|
||||
#foreach ($import in $importList)
|
||||
import ${import};
|
||||
#end
|
||||
@ -14,7 +18,11 @@ import ${import};
|
||||
* @author ${author}
|
||||
* @date ${datetime}
|
||||
*/
|
||||
#if($table.crud)
|
||||
#set($Entity="BaseEntity")
|
||||
#elseif($table.tree)
|
||||
#set($Entity="TreeEntity")
|
||||
#end
|
||||
public class ${ClassName} extends ${Entity}
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
@ -43,7 +51,7 @@ public class ${ClassName} extends ${Entity}
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if(!$table.isSuperColumn($column.javaField))
|
||||
#if($column.javaField > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||
#set($AttrName=$column.javaField)
|
||||
#else
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
@ -64,7 +72,7 @@ public class ${ClassName} extends ${Entity}
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
#foreach ($column in $columns)
|
||||
#if($column.javaField > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||
#set($AttrName=$column.javaField)
|
||||
#else
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ${packageName}.mapper;
|
||||
|
||||
import ${packageName}.domain.${ClassName};
|
||||
import java.util.List;
|
||||
import ${packageName}.domain.${ClassName};
|
||||
|
||||
/**
|
||||
* ${functionName}Mapper接口
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ${packageName}.service;
|
||||
|
||||
import ${packageName}.domain.${ClassName};
|
||||
import java.util.List;
|
||||
import ${packageName}.domain.${ClassName};
|
||||
|
||||
/**
|
||||
* ${functionName}Service接口
|
||||
|
410
ruoyi/src/main/resources/vm/vue/index-tree.vue.vm
Normal file
410
ruoyi/src/main/resources/vm/vue/index-tree.vue.vm
Normal file
@ -0,0 +1,410 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
||||
#foreach($column in $columns)
|
||||
#if($column.query)
|
||||
#set($dictType=$column.dictType)
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-input
|
||||
v-model="queryParams.${column.javaField}"
|
||||
placeholder="请输入${comment}"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
<el-option
|
||||
v-for="dict in ${column.javaField}Options"
|
||||
:key="dict.dictValue"
|
||||
:label="dict.dictLabel"
|
||||
:value="dict.dictValue"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-date-picker clearable size="small" style="width: 200px"
|
||||
v-model="queryParams.${column.javaField}"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
size="mini"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
||||
>新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="${businessName}List"
|
||||
row-key="${treeCode}"
|
||||
default-expand-all
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
>
|
||||
#foreach($column in $columns)
|
||||
#set($javaField=$column.javaField)
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($column.pk)
|
||||
#elseif($column.list && $column.htmlType == "datetime")
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && "" != $column.dictType)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" :formatter="${javaField}Format" />
|
||||
#elseif($column.list && "" != $javaField)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改${functionName}对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
#foreach($column in $columns)
|
||||
#set($field=$column.javaField)
|
||||
#if($column.insert && !$column.pk)
|
||||
#if(($column.usableColumn) || (!$column.superColumn))
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#set($dictType=$column.dictType)
|
||||
#if("" != $treeParentCode && $column.javaField == $treeParentCode)
|
||||
<el-form-item label="${comment}" prop="${treeParentCode}">
|
||||
<treeselect v-model="form.${treeParentCode}" :options="${businessName}Options" :normalizer="normalizer" placeholder="请选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select" && "" != $dictType)
|
||||
<el-form-item label="${comment}">
|
||||
<el-select v-model="form.${field}" placeholder="请选择${comment}">
|
||||
<el-option
|
||||
v-for="dict in ${field}Options"
|
||||
:key="dict.dictValue"
|
||||
:label="dict.dictLabel"
|
||||
:value="dict.dictValue"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select" && $dictType)
|
||||
<el-form-item label="${comment}">
|
||||
<el-select v-model="form.${field}" placeholder="请选择${comment}">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio" && "" != $dictType)
|
||||
<el-form-item label="${comment}">
|
||||
<el-radio-group v-model="form.${field}">
|
||||
<el-radio
|
||||
v-for="dict in ${field}Options"
|
||||
:key="dict.dictValue"
|
||||
:label="dict.dictValue"
|
||||
>{{dict.dictLabel}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio" && $dictType)
|
||||
<el-form-item label="${comment}">
|
||||
<el-radio-group v-model="form.${field}">
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-date-picker clearable size="small" style="width: 200px"
|
||||
v-model="form.${field}"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
||||
import Treeselect from "@riophae/vue-treeselect";
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
|
||||
export default {
|
||||
name: "${BusinessName}",
|
||||
components: { Treeselect },
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// ${functionName}表格数据
|
||||
${businessName}List: [],
|
||||
// ${functionName}树选项
|
||||
${businessName}Options: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
#foreach ($column in $columns)
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if(${column.dictType} != '')
|
||||
// $comment字典
|
||||
${column.javaField}Options: []#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#end
|
||||
#end
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
#foreach ($column in $columns)
|
||||
#if($column.query)
|
||||
$column.javaField: undefined#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#end
|
||||
#end
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
#foreach ($column in $columns)
|
||||
#if($column.required)
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [
|
||||
{ required: true, message: "$comment不能为空", trigger: "blur" }
|
||||
]#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
#foreach ($column in $columns)
|
||||
#if(${column.dictType} != '')
|
||||
this.getDicts("${column.dictType}").then(response => {
|
||||
this.${column.javaField}Options = response.data;
|
||||
});
|
||||
#end
|
||||
#end
|
||||
},
|
||||
methods: {
|
||||
/** 查询${functionName}列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
list${BusinessName}(this.queryParams).then(response => {
|
||||
this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 转换${functionName}数据结构 */
|
||||
normalizer(node) {
|
||||
if (node.children && !node.children.length) {
|
||||
delete node.children;
|
||||
}
|
||||
return {
|
||||
id: node.${treeCode},
|
||||
label: node.${treeName},
|
||||
children: node.children
|
||||
};
|
||||
},
|
||||
/** 查询部门下拉树结构 */
|
||||
getTreeselect() {
|
||||
list${BusinessName}().then(response => {
|
||||
this.${businessName}Options = [];
|
||||
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
|
||||
data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
||||
this.${businessName}Options.push(data);
|
||||
});
|
||||
},
|
||||
#foreach ($column in $columns)
|
||||
#if(${column.dictType} != '')
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
// $comment字典翻译
|
||||
${column.javaField}Format(row, column) {
|
||||
return this.selectDictLabel(this.${column.javaField}Options, row.${column.javaField});
|
||||
},
|
||||
#end
|
||||
#end
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
#foreach ($column in $columns)
|
||||
#if($column.htmlType == "radio")
|
||||
$column.javaField: "0"#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#else
|
||||
$column.javaField: undefined#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#end
|
||||
#end
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.getTreeselect();
|
||||
this.open = true;
|
||||
this.title = "添加${functionName}";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
this.getTreeselect();
|
||||
if (row != undefined) {
|
||||
this.form.${treeParentCode} = row.${treeCode};
|
||||
}
|
||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改${functionName}";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm: function() {
|
||||
this.#[[$]]#refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.${pkColumn.javaField} != undefined) {
|
||||
update${BusinessName}(this.form).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
add${BusinessName}(this.form).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
this.$confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function() {
|
||||
return del${BusinessName}(row.${pkColumn.javaField});
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.msgSuccess("删除成功");
|
||||
}).catch(function() {});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -22,7 +22,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
<el-option
|
||||
v-for="dict in ${column.javaField}Options"
|
||||
@ -33,7 +33,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
@ -230,6 +230,7 @@
|
||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
||||
|
||||
export default {
|
||||
name: "${BusinessName}",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
@ -288,6 +289,7 @@ export default {
|
||||
$column.javaField: [
|
||||
{ required: true, message: "$comment不能为空", trigger: "blur" }
|
||||
]#if($velocityCount != $columns.size()),#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
Reference in New Issue
Block a user