增加定时器功能

This commit is contained in:
zhangwei
2019-01-26 18:02:44 +06:00
parent 0fb4bf08a4
commit f90ef5ab85
47 changed files with 5923 additions and 356 deletions

18
pom.xml
View File

@@ -710,5 +710,23 @@
<artifactId>jersey-apache-connector</artifactId>
<version>2.23.1</version>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,43 @@
package com.nis.domain;
import com.nis.domain.configuration.BaseCfg;
/**
* 定时任务信息 schedule_info
* @author ThinkPad
*
*/
public class ScheduleCfg extends BaseCfg<ScheduleCfg>{
private static final long serialVersionUID = 7151915080876949497L;
private String name;//定时任务名称,预留
private String cronValid;//生效cron表达式
private String cronInvalid;//失效cron表达式
private String whereStr;//动态where 条件
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCronValid() {
return cronValid;
}
public void setCronValid(String cronValid) {
this.cronValid = cronValid;
}
public String getCronInvalid() {
return cronInvalid;
}
public void setCronInvalid(String cronInvalid) {
this.cronInvalid = cronInvalid;
}
public String getWhereStr() {
return whereStr;
}
public void setWhereStr(String whereStr) {
this.whereStr = whereStr;
}
}

View File

@@ -0,0 +1,66 @@
package com.nis.domain;
import java.util.Date;
import com.nis.domain.configuration.BaseCfg;
/**
* 定时任务执行信息 schedule_exce_log/schedule_exce_new
* `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`schedule_id` bigint(20) NOT NULL COMMENT 'schedule_info 表的主键',
`exce_time` datetime DEFAULT NULL COMMENT '最新执行时间',
`issue_status` int(255) DEFAULT NULL COMMENT '下发状态1生效0失效',
`issue_result` int(255) DEFAULT NULL COMMENT '下发结果1成功0失败',
`error_info` varchar(255) DEFAULT NULL COMMENT '下发失败原因',
`compile_id` bigint(20) DEFAULT NULL COMMENT '编译id',
* @author fang
*
*/
public class ScheduleExceInfo extends BaseCfg<ScheduleExceInfo>{
private static final long serialVersionUID = 7151915080876949497L;
private Long scheduleId;//定时器id
private Date exceTime;//下发时间
private Integer issueStatus;//下发 的状态
private Integer issueResult;//下发结果
private String errorInfo;//动态where 条件
private Integer isIssue;//是否需要下发配置1需要0不需要
public Long getScheduleId() {
return scheduleId;
}
public void setScheduleId(Long scheduleId) {
this.scheduleId = scheduleId;
}
public Date getExceTime() {
return exceTime;
}
public void setExceTime(Date exceTime) {
this.exceTime = exceTime;
}
public Integer getIssueStatus() {
return issueStatus;
}
public void setIssueStatus(Integer issueStatus) {
this.issueStatus = issueStatus;
}
public Integer getIssueResult() {
return issueResult;
}
public void setIssueResult(Integer issueResult) {
this.issueResult = issueResult;
}
public String getErrorInfo() {
return errorInfo;
}
public void setErrorInfo(String errorInfo) {
this.errorInfo = errorInfo;
}
public Integer getIsIssue() {
return isIssue;
}
public void setIsIssue(Integer isIssue) {
this.isIssue = isIssue;
}
}

View File

@@ -16,6 +16,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.nis.domain.BaseEntity;
import com.nis.domain.ScheduleCfg;
import com.nis.domain.SysMenu;
import com.nis.util.Constants;
import com.nis.util.StringUtil;
@@ -60,6 +61,14 @@ public class BaseCfg<T> extends BaseEntity<T> implements Cloneable{
protected Integer compileIsIssued;
protected String exType;//导出类型
protected String hColumns;//导出隐藏列
/**
* 定时任务信息
*/
//protected List<ScheduleCfg> schedules;
/**
* 定时任务信息2019年1月18日18:54:53 修改
*/
protected ScheduleCfg schedule;
private String commonGroupIds; //公共组织id(考虑一个compile存在多个asn组织的情况)
public String getCommonGroupIds() {
@@ -350,26 +359,24 @@ public class BaseCfg<T> extends BaseEntity<T> implements Cloneable{
*/
public void setFunctionId(Integer functionId) {
this.functionId = functionId;
if(!StringUtil.isEmpty(functionId) && StringUtil.isEmpty(this.menuNameCode)){
List<SysMenu> list = UserUtils.getMenuList();
}
public String getMenuNameCode() {
if(!StringUtil.isEmpty(this.functionId) && StringUtil.isEmpty(menuNameCode)){
List<SysMenu> list = UserUtils.getMenuCfgList();
if(!StringUtil.isEmpty(list)) {
for (SysMenu menu :list) {
if (!StringUtil.isEmpty(menu.getCode())
&&menu.getFunctionId()!=null
&& menu.getFunctionId().equals(functionId)
&& menu.getFunctionId().equals(this.functionId)
//&& menu.getFunctionId().equals(functionId)
) {
this.setMenuNameCode(menu.getCode());
break;
}
}
}
}
}
public String getMenuNameCode() {
return menuNameCode;
}
public void setMenuNameCode(String menuNameCode) {
@@ -982,5 +989,12 @@ public class BaseCfg<T> extends BaseEntity<T> implements Cloneable{
public void setDoBlackList(Integer doBlackList) {
this.doBlackList = doBlackList;
}
public ScheduleCfg getSchedule() {
return schedule;
}
public void setSchedule(ScheduleCfg schedule) {
this.schedule = schedule;
}
}

View File

@@ -54,6 +54,8 @@ public class ToUpdateMaatBeanStatus implements Serializable{
@Expose
private Integer isValid;
@Expose
private Integer service;
@Expose
@SerializedName("opTime")
private Date auditTime;
public Integer getCompileId() {
@@ -74,6 +76,12 @@ public class ToUpdateMaatBeanStatus implements Serializable{
public void setAuditTime(Date auditTime) {
this.auditTime = auditTime;
}
public Integer getService() {
return service;
}
public void setService(Integer service) {
this.service = service;
}
}
public String getVersion() {

View File

@@ -0,0 +1,93 @@
package com.nis.persistence.interceptor;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import com.nis.domain.ScheduleCfg;
import com.nis.domain.configuration.BaseCfg;
import com.nis.util.ServiceConfigTemplateUtil;
/**
* 定时任务 拦截器
* 1、拦截 select 操作
* 2、判断是否 form 查询配置主表
* 3、如果是配置主表查询对应的 scheduleCfg信息
* @author fang
*
*/
@Intercepts({@Signature(type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class ScheduleSelectInterceptor extends BaseInterceptor{
private static final long serialVersionUID = -265785145929843646L;
private static final Logger logger = Logger.getLogger(ScheduleSelectInterceptor.class);
@Override
@SuppressWarnings("all")
public Object intercept(Invocation invocation) throws Throwable {
final MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
final Executor executor = (Executor)invocation.getTarget();
// select sql 查询结果
Object result = invocation.proceed();
if(result != null ) {
if(result instanceof Collection) {
Collection c = (Collection)result;
// if(c.size()==1) {//如果只查询一个 配置可以判定为是 form update 页面查询
if(c.size() >0) {//配置列表需要查询是否为定时任务,所以需要遍历
Iterator iterator = c.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
if(next instanceof BaseCfg<?>) {
BaseCfg cfg = (BaseCfg)next;
//结果集的类名
String simpleName = next.getClass().getSimpleName();
//根据类名查找对应的 表名
String tableName = ServiceConfigTemplateUtil.getCfgTableNameByClassName(simpleName);
if(tableName != null) {//是配置主表
Configuration configuration = mappedStatement.getConfiguration();
MappedStatement scheduleStmt = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.findScheduleList");
ScheduleCfg sc = new ScheduleCfg();
sc.setTableName(tableName);
sc.setCfgId(cfg.getCfgId());
sc.setCompileId(cfg.getCompileId());
//executor.clearLocalCache();
List<ScheduleCfg> schedules = executor.query(scheduleStmt, sc, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
if(schedules != null&& schedules.size() > 0) {
cfg.setSchedule(schedules.get(0));
}
logger.debug(String.format("配置bean中赋值scheduleCfg,表名:%s,类名:%s,cfgId:%s,compileId:%s,schedules num:%s", tableName,simpleName,sc.getCfgId(),sc.getCompileId(),schedules==null?0:schedules.size()));
}
}else{
break;
}
}
}
}
}
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}

View File

@@ -0,0 +1,389 @@
package com.nis.persistence.interceptor;
import java.lang.reflect.Array;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.google.common.collect.Lists;
import com.nis.domain.ScheduleCfg;
import com.nis.domain.ScheduleExceInfo;
import com.nis.domain.configuration.BaseCfg;
import com.nis.util.ServiceConfigTemplateUtil;
import com.nis.web.security.UserUtils;
import jersey.repackaged.com.google.common.collect.Sets;
/**
* 定时任务 拦截器
* 1、拦截insert,update,delete操作
* 2、判断是否是需要下发配置的表
* 3、如果是需要下发配置的表则同时将数据保存到schedule_cfg表中并调用定时任务
* @author fang
*
*/
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ScheduleUpdateInterceptor extends BaseInterceptor{
private static final long serialVersionUID = -265785145929843646L;
private static final Logger logger = Logger.getLogger(ScheduleUpdateInterceptor.class);
private static final String TABLE_NAME_INSERT_REG = "^\\s*insert\\s+into\\s+([\\w_-]+)\\s*\\(";
private static final Pattern TABLE_NAME_INSERT_PATTERN = Pattern.compile(TABLE_NAME_INSERT_REG, Pattern.CASE_INSENSITIVE);//大小写
private static final String TABLE_NAME_UPDATE_REG = "^\\s*update\\s+([\\w_-]+)";
private static final Pattern TABLE_NAME_UPDATE_PATTERN = Pattern.compile(TABLE_NAME_UPDATE_REG, Pattern.CASE_INSENSITIVE);//大小写
private static final String TABLE_NAME_DELETE_REG = "^\\s*delete\\s+from\\s+([\\w_-]+)";
private static final Pattern TABLE_NAME_DELETE_PATTERN = Pattern.compile(TABLE_NAME_DELETE_REG, Pattern.CASE_INSENSITIVE);//大小写
/**
* 排除拦截的id
*/
private static final Set<String> EXCLUDE_MAPPER_IDS = Sets.newHashSet();
static {
EXCLUDE_MAPPER_IDS.add("com.nis.web.dao.SchedulerDao.updateCfgTableStatus");
EXCLUDE_MAPPER_IDS.add("com.nis.web.dao.basics.ServiceDictInfoDao");
}
/**
* is_valid 字段名
*/
private static final String IS_VALID_COLUMN = "is_valid";
/**
* is_audit 字段名
*/
private static final String IS_AUDIT_COLUMN = "is_audit";
@Override
@SuppressWarnings("all")
public Object intercept(Invocation invocation) throws Throwable {
final MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
final Executor executor = (Executor)invocation.getTarget();
Object parameter = invocation.getArgs()[1];//被拦截的 sql 参数
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
Object result = invocation.proceed();//被拦截的 sql 操作 继续执行
String curProceedId = mappedStatement.getId();
//不需要拦截的操作直接返回结果
if(EXCLUDE_MAPPER_IDS.contains(curProceedId)) {
return result;
}
String tableName = null;//操作的表名
//mybatis 整个mapper 信息
Configuration configuration = mappedStatement.getConfiguration();
//被拦截的 sql语句
String sql = boundSql.getSql();
//所有需要拦截的表名
Set<String> tableNames = ServiceConfigTemplateUtil.getCompileTableName();
switch (mappedStatement.getSqlCommandType()) {
case INSERT://新增配置
Matcher insertMatcher = TABLE_NAME_INSERT_PATTERN.matcher(sql);
tableName = insertMatcher.find()?insertMatcher.group(1):tableName;
if(tableName != null && tableNames.contains(tableName.toLowerCase())) {
insertCfg(executor,parameter, configuration,tableName);
}
break;
case UPDATE://更新配置
Matcher updateMatcher = TABLE_NAME_UPDATE_PATTERN.matcher(sql);
tableName = updateMatcher.find()?updateMatcher.group(1):tableName;
if(tableName != null && tableNames.contains(tableName.toLowerCase())) {
updateCfg(executor,boundSql, configuration,tableName);
}
break;
case DELETE://删除配置
Matcher deleteMatcher = TABLE_NAME_DELETE_PATTERN.matcher(sql);
tableName = deleteMatcher.find()?deleteMatcher.group(1):tableName;
if(tableName != null && tableNames.contains(tableName.toLowerCase())) {
deleteCfg(executor,parameter, configuration,tableName);
}
break;
default:
break;
}
logger.debug(sql);
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
/**
* @throws SQLException
*
*/
@SuppressWarnings("all")
private void insertCfg(Executor executor,Object parameterObject,Configuration configuration,String tableName) throws SQLException {
List<BaseCfg> cfgList = Lists.newArrayList();
//确保 单个,批量都适用
if(parameterObject instanceof BaseCfg<?>) {//单个添加
BaseCfg<?> baseCfg = (BaseCfg<?>)parameterObject;
cfgList.add(baseCfg);
}else if(parameterObject instanceof Collection) {
Collection<BaseCfg<?>> bcCollection = (Collection<BaseCfg<?>>)parameterObject;
cfgList.addAll(bcCollection);
}else if(parameterObject.getClass().isArray()) {
int length = Array.getLength(parameterObject);
for(int i = 0;i< length;i++) {
BaseCfg<?> baseCfg = (BaseCfg<?>)Array.get(parameterObject, i);
cfgList.add(baseCfg);
}
}
//整理需要 insert 的 schedule_cfg 的数据
List<ScheduleCfg> scheduleList = Lists.newArrayList();
for(BaseCfg<?> baseCfg : cfgList) {
baseCfg.setIsValid(0);//设置默认值
baseCfg.setIsAudit(0);//设置默认值
ScheduleCfg scList = copyScheduleCfgFromBaseCfg(baseCfg, tableName);
if(scList!=null){
scheduleList.add(scList);
}
}
if(scheduleList.size() > 0) {
for(ScheduleCfg sc : scheduleList) {
MappedStatement statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.insert");
executor.update(statement, sc);
}
}
}
/**
*
*/
@SuppressWarnings("all")
private void updateCfg(Executor executor,BoundSql boundSql,Configuration configuration,String tableName) throws SQLException {
/*
* 条件1 is_valid=0,is_audit=0; 未生效之前修改,来自修改页面
*1、首先将所有相关定时任务信息取消
*2、 新增 定时任务信息
*/
Object parameterObject = boundSql.getParameterObject();
if(parameterObject instanceof BaseCfg) {
BaseCfg bc = (BaseCfg)parameterObject;
Integer isValid = bc.getIsValid();
Integer isAudit = bc.getIsAudit();
Integer compileId = bc.getCompileId();
Long cfgId = bc.getCfgId();
if(isValid == 0 && isAudit == 0) {
ScheduleCfg sc = new ScheduleCfg();
sc.setCompileId(compileId);
sc.setEditorId(bc.getEditorId());
sc.setEditTime(bc.getEditTime());
sc.setCfgId(cfgId);
//根据 compileId 删除之前的
MappedStatement statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.deleteByCompileId");
executor.update(statement, sc);
//新增 更改的
ScheduleCfg schedule = copyScheduleCfgFromBaseCfg(bc, tableName);
if(schedule != null ) {
statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.insert");
executor.update(statement, schedule);
//配置信息新增,或取消之后重新修改,需要修改 exce_new表的状态
statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.updateScheduleExceNew");
ScheduleExceInfo exceNew = new ScheduleExceInfo();
exceNew.setCompileId(compileId);
exceNew.setIssueStatus(1);
exceNew.setIsIssue(1);//定时任务执行时需要下发配置
executor.update(statement, exceNew);
}
return;
}
}
//完整的sql语句已经完成 ? 替换
String sql = showSql(configuration, boundSql);
log.debug(String.format("cfg update sql : " , sql));
//其它剩余基本判定为 修改状态的 update
MySqlStatementParser parser = new MySqlStatementParser(sql);
MySqlUpdateStatement updateSqlStmt = (MySqlUpdateStatement)parser.parseStatement();
List<SQLUpdateSetItem> items = updateSqlStmt.getItems();
/* 分别获取 is_audit & is_valid 的值*/
Integer isValid = null;
Integer isAudit = null;
for(SQLUpdateSetItem item : items) {
if(IS_VALID_COLUMN.equalsIgnoreCase(item.getColumn().toString())) {
isValid = Integer.valueOf(item.getValue().toString());
continue;
}
if(IS_AUDIT_COLUMN.equalsIgnoreCase(item.getColumn().toString())) {
isAudit = Integer.valueOf(item.getValue().toString());
continue;
}
if(isValid != null && isAudit != null) {
break;
}
}
//isValid 和 isAudit 同时为空,目前发现有 取消来函的 update 操作有此情况
if(isValid == null && isAudit == null) {
return;
}
//获取当前的update 条件
String whereStr = updateSqlStmt.getWhere().toString();
StringBuilder whereSb = new StringBuilder();
whereSb.append(" and table_name = '");
whereSb.append(tableName);
whereSb.append("' and ( ");
whereSb.append(whereStr);
whereSb.append(" )");
//根据当前的 update 条件 查出所有符合条件的 schedule_cfg 数据
MappedStatement scheduleStmt = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.findScheduleList");
ScheduleCfg sc = new ScheduleCfg();
sc.setWhereStr(whereSb.toString());
List<ScheduleCfg> schedules = executor.query(scheduleStmt, sc, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
if(schedules != null && schedules.size() > 0) {//有符合条件的 定时任务
Set<Integer> compileSet = Sets.newHashSet();//保存操作的所有 compileId
Date now = new Date();//当前时间
//1、将符合条件的是 ScheduleCfg update del_flag = 0
for(ScheduleCfg scfg : schedules) {
compileSet.add(scfg.getCompileId());
scfg.setEditorId(UserUtils.getUser().getId());
scfg.setEditTime(now);
MappedStatement statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.deleteByCompileId");
executor.update(statement, scfg);
}
//2、把原信息 重新保存,并修改 is_valid ,is_audit 状态
for(ScheduleCfg scfg : schedules) {
MappedStatement statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.insert");
scfg.setIsValid(isValid);
scfg.setIsAudit(isAudit);
executor.update(statement, scfg);
}
//手动 审核通过,立即生效时 已经下发,修改 exce_new 表的是否需要下发字段为 不需要 0
if(isValid == 1 && isAudit == 1) {
for(Integer ci : compileSet) {
MappedStatement statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.findScheduleExceNew");
ScheduleExceInfo se = new ScheduleExceInfo();
se.setCompileId(ci);
se.setIsValid(isValid);
List<ScheduleExceInfo> seList = executor.query(statement, se, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
if(seList == null || seList.size() < 1) {//没有执行记录,新增一条
//配置信息新增,或取消之后重新修改,需要修改 exce_new表的状态
statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.insertScheduleExceNew");
ScheduleExceInfo exceNew = new ScheduleExceInfo();
exceNew.setCompileId(ci);
exceNew.setIssueStatus(1);
exceNew.setIsIssue(0);//已经下发,定时任务不需要下发
exceNew.setExceTime(new Date());
executor.update(statement, exceNew);
}else {
//配置信息新增,或取消之后重新修改,需要修改 exce_new表的状态
statement = configuration.getMappedStatement("com.nis.web.dao.SchedulerDao.updateScheduleExceNew");
ScheduleExceInfo exceNew = new ScheduleExceInfo();
exceNew.setCompileId(ci);
exceNew.setIssueStatus(1);
exceNew.setIsIssue(0);//已经下发,定时任务不需要下发
executor.update(statement, exceNew);
}
}
}
}
}
/**
* 暂时没有发现有 删除操作
*/
@SuppressWarnings("all")
private void deleteCfg(Executor executor,Object parameterObject,Configuration configuration,String tableName) throws SQLException {
}
/**
* 从 basecfg 实体类中获取 schedule cfg
* @param baseCfg
* @param tableName
* @return
*/
private ScheduleCfg copyScheduleCfgFromBaseCfg(BaseCfg<?> baseCfg,String tableName){
ScheduleCfg schedule = baseCfg.getSchedule();
if(schedule != null ) {
BeanUtils.copyProperties(baseCfg, schedule,new String[]{"userRegion1","userRegion2","userRegion3","userRegion4","userRegion5"});
schedule.setTableName(tableName);
}
return schedule;
}
/*如果参数是String则添加单引号 如果是日期,则转换为时间格式器并加单引号; 对参数是null和不是null的情况作了处理*/
private static String getParameterValue(Object obj) {
String value = null;
if (obj instanceof String) {
value = "'" + obj.toString() + "'";
} else if (obj instanceof Date) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.getDefault());
value = "'" + formatter.format(new Date()) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "null";
}
}
return value;
}
// 进行?的替换
public static String showSql(Configuration configuration, BoundSql boundSql) {
Object parameterObject = boundSql.getParameterObject(); // 获取参数
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
String sql = boundSql.getSql().replaceAll("[\\s]+", " "); // sql语句中多个空格都用一个空格代替
if (parameterMappings != null && parameterMappings.size() >0 && parameterObject != null) {
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); // 获取类型处理器注册器类型处理器的功能是进行java类型和数据库类型的转换<br>       // 如果根据parameterObject.getClass()可以找到对应的类型,则替换
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject)));
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);// MetaObject主要是封装了originalObject对象提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作
for (ParameterMapping parameterMapping : parameterMappings) {
String propertyName = parameterMapping.getProperty();
if (metaObject.hasGetter(propertyName)) {
Object obj = metaObject.getValue(propertyName);
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName); // 该分支是动态sql
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
}else{sql=sql.replaceFirst("\\?","缺失");}//打印出缺失,提醒该参数缺失并防止错位
}
}
}
return sql;
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,519 @@
package com.nis.quartz;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.quartz.CalendarIntervalScheduleBuilder;
import org.quartz.CalendarIntervalTrigger;
import org.quartz.CronScheduleBuilder;
import org.quartz.DateBuilder;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;
import org.quartz.ScheduleBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CalendarIntervalTriggerImpl;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.spi.MutableTrigger;
import com.nis.domain.ScheduleCfg;
import com.nis.util.Constants;
import com.nis.util.DateUtil;
import com.nis.util.DateUtils;
import com.nis.util.StringUtils;
import com.nis.web.dao.SchedulerDao;
import com.nis.web.service.SpringContextHolder;
/**
* 定时任务 配置定时任务加载
* 1、每 n s 执行一次,每次读取 schedule_cfg 最新的数据
* 2、删除或新增 定时任务
* 3、单线程执行
* @author fang
*
*/
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class ScheduleCfgJob implements Job {
private static final Logger log = Logger.getLogger(ScheduleCfgJob.class);
/**
* 状态组格式statusGroup-compileId
*/
private static final String STATUS_GROUP = "statusGroup-";
private static final String STATUS_JOB = "STATUS-JOB";
/**
* 生效标识valid-cronexp
*/
private static final String VALID_KEY = "valid-";
/**
* 失效标识invalid-cronexp
*/
private static final String INVALID_KEY = "invalid-";
private static final JobKey STATUS_JOBKEY = JobKey.jobKey(STATUS_JOB, "statusGroup");
private static final JobDetail STATUS_JOBDETAIL = JobBuilder.newJob(ScheduleStatusJob.class)
.withIdentity(STATUS_JOBKEY)
.storeDurably(true)
.build();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Scheduler scheduler = context.getScheduler();
SchedulerDao dao = SpringContextHolder.getBean(SchedulerDao.class);
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
long scheduleCfgId = dataMap.get("scheduleCfgId") == null ? 0:dataMap.getLong("scheduleCfgId");
long limit = dataMap.get("limit") == null ? 1000:dataMap.getLong("limit");
log.info(String.format("定时配置任务开始执行scheduleCfgId:%s,limit:%s",scheduleCfgId,limit ));
List<ScheduleCfg> newlyCfg = null;
int totalNum = 0;
do {
newlyCfg = dao.findNewlyCfg(scheduleCfgId, limit);
if(newlyCfg != null && newlyCfg.size() > 0) {
totalNum += newlyCfg.size();
for(ScheduleCfg cfg : newlyCfg) {//先取消之前的定时配置
Integer compileId = cfg.getCompileId();
try {
//取消之前所有的 trigger
GroupMatcher<TriggerKey> groupMatcher= GroupMatcher.triggerGroupEquals(STATUS_GROUP + compileId);
Set<TriggerKey> triggerKeys = scheduler.getTriggerKeys(groupMatcher);
if(triggerKeys != null && triggerKeys.size() > 0) {
for(TriggerKey tk : triggerKeys) {
scheduler.unscheduleJob(tk);
}
log.info(String.format("定时任务取消成功compile:%s", compileId));
}
} catch (Exception e) {
log.error(String.format("定时任务取消异常compileId:%s", compileId),e);
}
}
for(ScheduleCfg cfg : newlyCfg) {
Integer compileId = cfg.getCompileId();
try {
//判断状态,重新添加最新的 trigger
Integer isValid = cfg.getIsValid();
Integer isAudit = cfg.getIsAudit();
//添加定时任务的条件
if((isValid == 1 && isAudit == 1) || (isValid == 0 && isAudit == 0)) {
//添加定时任务包括valid 和 invalid
addJob(scheduler, cfg);
log.info(String.format("定时任务添加成功compile:%s", compileId));
}
} catch (Exception e) {
log.error(String.format("定时任务更新异常compileId:%s", compileId),e);
}
}
//最后 保存此次 最后的id
ScheduleCfg lastCfg = newlyCfg.get(newlyCfg.size() -1);
scheduleCfgId = lastCfg.getId();
dataMap.put("scheduleCfgId", scheduleCfgId);
log.info(String.format("加载定时任务total num :%s", newlyCfg.size()));
}
} while (newlyCfg != null && newlyCfg.size() > 0);
log.info(String.format("定时配置任务结束执行total num:%s",totalNum));
}
/**
* 将定时任务信息添加到 定时器框架中调度
* @param scheduler
* @param cfg
* @throws SchedulerException
*/
/*public static void addJob(Scheduler scheduler,ScheduleCfg cfg) throws SchedulerException {
Integer compileId = cfg.getCompileId();
String cronValid = cfg.getCronValid();
String cronInvalid = cfg.getCronInvalid();
Trigger validTrigger = createTrigger(cronValid, compileId, true, cfg);
Trigger invalidTrigger = createTrigger(cronInvalid, compileId, false, cfg);
boolean jobExist = scheduler.checkExists(STATUS_JOBKEY);
if(!jobExist) {//判断 job 是否存在,不存在添加
scheduler.addJob(STATUS_JOBDETAIL, false);
}
boolean checkExists = scheduler.checkExists(validTrigger.getKey());
if(!checkExists) {//判断 valid trigger 是否存在,不存在添加
scheduler.scheduleJob(validTrigger);
}else {
log.warn(String.format("Trigger already exists:%s ", validTrigger.getKey().toString()));
}
checkExists = scheduler.checkExists(invalidTrigger.getKey());
if(!checkExists) {//判断 invalid trigger 是否存在,不存在添加
scheduler.scheduleJob(invalidTrigger);
}else {
log.warn(String.format("Trigger already exists:%s ", invalidTrigger.getKey().toString()));
}
}*/
public static void addJob(Scheduler scheduler,ScheduleCfg cfg) throws SchedulerException {
List<Trigger> triList = createTrigger(cfg);
boolean jobExist = scheduler.checkExists(STATUS_JOBKEY);
if(!jobExist) {//判断 job 是否存在,不存在添加
scheduler.addJob(STATUS_JOBDETAIL, false);
}
for(Trigger tri : triList) {
boolean checkExists = scheduler.checkExists(tri.getKey());
if(!checkExists) {//判断 valid trigger 是否存在,不存在添加
log.debug(String.format("定时任务添加,%s", tri.getKey()));
scheduler.scheduleJob(tri);
log.info(String.format("定时任务添加成功,%s", tri.getKey()));
}else {
log.warn(String.format("Trigger already exists:%s ", tri.getKey().toString()));
}
}
}
/**
* 将页面配置的内容 转换成 trigger
* @param cfg
* @return
*/
public static List<Trigger> createTrigger(ScheduleCfg cfg){
String mode = cfg.getUserRegion1().toUpperCase();//定时任务运行模式:一次,每天,每周,每月
List<Trigger> triList = null;
switch (mode) {
case "SINGLE"://单次运行
triList = createSimpleTrigger(cfg);
break;
case "EVERYDAY"://每天运行 0 0 0 2/1 * ? ,不符合要求,定义每天都执行,然后在 代码判断 间隔时间
triList = createCalendarIntervalTrigger(cfg);
break;
case "EVERYWEEK"://每周运行
triList = createCalendarIntervalTrigger(cfg);
break;
case "EVERYMONTH"://每月运行
triList = createEveryMonthTrigger(cfg);
break;
default:
log.warn(String.format("unknown mode : %s ", mode));
break;
}
return triList;
}
/**
* 将时间转换成 时分秒
* @param time
* @return
*/
public static List<Integer> parseTime(String time) {
if(StringUtils.isNoneBlank(time)) {
String[] split = time.split(":");
List<Integer> tl = new ArrayList<Integer>(3);
for(String s : split) {
tl.add(Integer.valueOf(s));
}
return tl;
}
return null;
}
public static Trigger createCronTrigger(String cron,Integer compileId,boolean isValid,ScheduleCfg cfg) {
String triggerName = isValid ? (VALID_KEY + cron) : (INVALID_KEY + cron);
JobDataMap dataMap = new JobDataMap();
dataMap.put("isValid", isValid);
dataMap.put("cfg", cfg);
return TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triggerName, STATUS_GROUP+compileId))
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.build();
}
/**
* 一次执行
* @param cfg
* @return
*/
public static List<Trigger> createSimpleTrigger(ScheduleCfg cfg){
List<Trigger> triList = new ArrayList<Trigger>();
Integer compileId = cfg.getCompileId();
String cronValid = cfg.getCronValid();
String cronInvalid = cfg.getCronInvalid();
Date validDate = DateUtil.convertStringToDate(cronValid, Constants.COMMON_DATE_FORMAT);
Date invalidDate = DateUtil.convertStringToDate(cronInvalid, Constants.COMMON_DATE_FORMAT);
JobDataMap dataMap = new JobDataMap();
dataMap.put("isValid", true);
dataMap.put("cfg", cfg);
String triName = VALID_KEY + cfg.getUserRegion1() + "_" + cronValid;
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(validDate)
.build();
triList.add(trigger);
dataMap = new JobDataMap();
dataMap.put("isValid", false);
dataMap.put("cfg", cfg);
triName = INVALID_KEY + cfg.getUserRegion1() + "_" + cronInvalid;
trigger = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(invalidDate)
.build();
triList.add(trigger);
return triList;
}
/**
* 间隔 n 天 或 n 周执行
* @param cfg
* @return
*/
public static List<Trigger> createCalendarIntervalTrigger(ScheduleCfg cfg) {
List<Trigger> triList = new ArrayList<Trigger>();
Integer compileId = cfg.getCompileId();
String cronValid = cfg.getCronValid();
String cronInvalid = cfg.getCronInvalid();
String dayOrWeek = cfg.getUserRegion1();
Integer interval = Integer.valueOf(cfg.getUserRegion2());
List<Integer> validList = parseTime(cronValid);
List<Integer> invalidList = parseTime(cronInvalid);
Date validStartTime = DateBuilder.todayAt(validList.get(0), validList.get(1), validList.get(2));
Date invalidTime = DateBuilder.todayAt(invalidList.get(0), invalidList.get(1), invalidList.get(2));
CalendarIntervalScheduleBuilder intervalBuilder = null;
if("EVERYDAY".equalsIgnoreCase(dayOrWeek)) {
intervalBuilder = CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInDays(interval);
//valid
JobDataMap dataMap = new JobDataMap();
dataMap.put("isValid", true);
dataMap.put("cfg", cfg);
String triName = VALID_KEY + dayOrWeek+"("+interval+")" + "_" + DateUtils.formatDate(validStartTime, Constants.COMMON_DATE_FORMAT);
Trigger validTri = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(intervalBuilder)
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(validStartTime)
.build();
triList.add(validTri);
//invalid
dataMap = new JobDataMap();
dataMap.put("isValid", false);
dataMap.put("cfg", cfg);
triName = INVALID_KEY + dayOrWeek +"("+interval+")" + "_" + DateUtils.formatDate(invalidTime, Constants.COMMON_DATE_FORMAT);
validTri = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(intervalBuilder)
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(invalidTime)
.build();
triList.add(validTri);
}else if("EVERYWEEK".equalsIgnoreCase(dayOrWeek)) {
intervalBuilder = CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInWeeks(interval);
String[] weeks = cfg.getUserRegion3().split(",");
for(String week : weeks) {
if(StringUtils.isNoneBlank(week)) {
Date temp = closestAfterWeek(validStartTime, Integer.valueOf(week));
JobDataMap dataMap = new JobDataMap();
dataMap.put("isValid", true);
dataMap.put("cfg", cfg);
String triName = VALID_KEY + dayOrWeek +week+"("+interval+")" + "_" + DateUtils.formatDate(temp, Constants.COMMON_DATE_FORMAT);
Trigger validTri = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(intervalBuilder)
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(temp)
.build();
triList.add(validTri);
//invalid
dataMap = new JobDataMap();
dataMap.put("isValid", false);
dataMap.put("cfg", cfg);
temp = closestAfterWeek(invalidTime, Integer.valueOf(week));
triName = INVALID_KEY + dayOrWeek +week+"("+interval+")" + "_" + DateUtils.formatDate(temp, Constants.COMMON_DATE_FORMAT);
validTri = TriggerBuilder.newTrigger()
.withIdentity(createTiggerKey(triName, STATUS_GROUP+compileId))
.withSchedule(intervalBuilder)
.usingJobData(dataMap)
.forJob(STATUS_JOBDETAIL)
.startAt(temp)
.build();
triList.add(validTri);
}
}
}
return triList;
}
/**
* 每月 执行
* @param cfg
* @return
*/
public static List<Trigger> createEveryMonthTrigger(ScheduleCfg cfg){
String dayWeek = cfg.getUserRegion3();
String cronInvalid = cfg.getCronInvalid();
String cronValid = cfg.getCronValid();
StringBuilder cronSb = new StringBuilder();
Trigger trigger = null;
List<Integer> validList = parseTime(cronValid);//time 转换
List<Integer> invalidList = parseTime(cronInvalid);//time 转换
List<Trigger> triList = new ArrayList<Trigger>();
String userRegion4 = cfg.getUserRegion4().toUpperCase();
if("day".equalsIgnoreCase(dayWeek)) {//指定天
boolean hasL = userRegion4.contains("L");
StringBuilder chooseSb = new StringBuilder();
for(String str : userRegion4.split(",")) {
if(!"L".equalsIgnoreCase(str.trim())) {
chooseSb.append(",").append(str);
}
}
chooseSb.deleteCharAt(0);
cronSb.append(validList.get(2)).append(" ")//秒
.append(validList.get(1)).append(" ")//分
.append(validList.get(0)).append(" ")//小时
.append(chooseSb.toString()).append(" ")//日
.append(cfg.getUserRegion2()).append(" ")//月
.append("?").append(" ");//周
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), true, cfg);
triList.add(trigger);
cronSb.setLength(0);
cronSb.append(invalidList.get(2)).append(" ")//秒
.append(invalidList.get(1)).append(" ")//分
.append(invalidList.get(0)).append(" ")//小时
.append(chooseSb.toString()).append(" ")//日
.append(cfg.getUserRegion2()).append(" ")//月
.append("?").append(" ");//周
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), false, cfg);
triList.add(trigger);
if(hasL) {// 月的最后一天quartz 不支持 1,L 这种指定,所以 L单独处理一下
cronSb.setLength(0);
cronSb.append(validList.get(2)).append(" ")//秒
.append(validList.get(1)).append(" ")//分
.append(validList.get(0)).append(" ")//小时
.append("L").append(" ")//日
.append(cfg.getUserRegion2()).append(" ")//月
.append("?").append(" ");//周
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), true, cfg);
triList.add(trigger);
cronSb.setLength(0);
cronSb.append(invalidList.get(2)).append(" ")//秒
.append(invalidList.get(1)).append(" ")//分
.append(invalidList.get(0)).append(" ")//小时
.append("L").append(" ")//日
.append(cfg.getUserRegion2()).append(" ")//月
.append("?").append(" ");//周
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), false, cfg);
triList.add(trigger);
}
}else if ("week".equalsIgnoreCase(dayWeek)) {//指定周1#2: 第一周的周二4L:最后一周的周四
for(String nthWeek : userRegion4.split(",")) {//第几周
for(String week : cfg.getUserRegion5().split(",")) {//星期几
cronSb.setLength(0);
cronSb.append(validList.get(2)).append(" ")//秒
.append(validList.get(1)).append(" ")//分
.append(validList.get(0)).append(" ")//小时
.append("?").append(" ")//日
.append(cfg.getUserRegion2()).append(" ");//月
if("L".equalsIgnoreCase(nthWeek)) {
cronSb.append(week).append("L");//周
}else {
cronSb.append(week).append("#").append(nthWeek);//周
}
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), true, cfg);
triList.add(trigger);
cronSb.setLength(0);
cronSb.append(invalidList.get(2)).append(" ")//秒
.append(invalidList.get(1)).append(" ")//分
.append(invalidList.get(0)).append(" ")//小时
.append("?").append(" ")//日
.append(cfg.getUserRegion2()).append(" ");//月
if("L".equalsIgnoreCase(nthWeek)) {
cronSb.append(week).append("L");//周
}else {
cronSb.append(week).append("#").append(nthWeek);//周
}
trigger = createCronTrigger(cronSb.toString(), cfg.getCompileId(), false, cfg);
triList.add(trigger);
}
}
}
return triList;
}
/**
* 查找最近的 星期几 ,包括今天
* @param date
* @param w 周一开始 1 -7
* @return
*/
public static Date closestAfterWeek(Date date,int w) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int i = cal.get(Calendar.DAY_OF_WEEK);//周日开始 1-7
i = (i==1)? 7: i-1;//转换为 周一到 周日 1-7
cal.add(Calendar.DAY_OF_MONTH, (i>w)?(7-(i-w)) : (w-i));
return cal.getTime();
}
public static TriggerKey createTiggerKey(String name,String group) {
TriggerKey key = new TriggerKey(name, group);
return key;
}
/**
* jquery cron 生成的cron 表达式quartz 不能直接使用,需要做些修改
* @param cron
* @return
*/
public static String modifyCronExp(String cron) {
String[] cronArr = cron.split("\\s");
if("*".equals(cronArr[4])) {
cronArr[4] = "?";
}else {
cronArr[3] = "*";
cronArr[2] = "?";
}
return "0 " + StringUtils.join(cronArr, " ");
}
public static void main(String[] args) {
CronTriggerImpl cron = new CronTriggerImpl();
try {
String exp = "0 0 0 ? 1,2 1#4";
cron.setCronExpression(exp);
System.out.println(cron);
} catch (ParseException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,38 @@
package com.nis.quartz;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.nis.domain.ScheduleCfg;
import com.nis.web.service.ScheduleService;
import com.nis.web.service.SpringContextHolder;
/**
* 定时任务 真正执行类
* 配置状态下发
* 从trigger 的 jobDataMap 中取出 相关数据compile,isValid
* @author fang
*
*/
public class ScheduleStatusJob implements Job{
private static final Logger log = Logger.getLogger(ScheduleStatusJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//从trigger中 获取 配置信息
JobDataMap jobDataMap = context.getTrigger().getJobDataMap();
boolean isValid = jobDataMap.getBoolean("isValid");
ScheduleCfg cfg = (ScheduleCfg)jobDataMap.get("cfg");
Integer compileId = cfg.getCompileId();
log.debug(String.format("任务开始执行compileId:%s,isValid:%s",compileId,isValid ));
//配置下发,并修改 配置表的状态,保存下发记录等
ScheduleService scheduleService = SpringContextHolder.getBean(ScheduleService.class);
scheduleService.issueCompileInfo(cfg, isValid?1:0);
log.debug(String.format("任务开始执行compileId:%s,isValid:%s",compileId,isValid ));
}
}

View File

@@ -0,0 +1,690 @@
package com.nis.util;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import com.google.common.collect.Lists;
import com.googlecode.ipv6.IPv6Address;
import com.googlecode.ipv6.IPv6Network;
import com.nis.domain.basics.AsnIpCfg;
import com.nis.domain.configuration.AppIpCfg;
import com.nis.domain.configuration.BaseCfg;
import com.nis.domain.configuration.BaseIpCfg;
import com.nis.domain.configuration.BaseStringCfg;
import com.nis.domain.configuration.ComplexkeywordCfg;
import com.nis.domain.configuration.FileDigestCfg;
import com.nis.domain.configuration.IpPortCfg;
import com.nis.domain.maat.MaatCfg.DigestCfg;
import com.nis.domain.maat.MaatCfg.GroupCfg;
import com.nis.domain.maat.MaatCfg.IpCfg;
import com.nis.domain.maat.MaatCfg.NumBoundaryCfg;
import com.nis.domain.maat.MaatCfg.StringCfg;
public class ConfigConvertUtil {
private static Logger logger = LoggerFactory.getLogger(ConfigConvertUtil.class);
/**
* 配置域转换
* @param ipList
* @param strList
* @param complexStrList
* @param numList
* @param fileList
* @param regionIds
* @param groupIds
* @param entity
* @param compileId
* @param auditTime
* @param groupRelationList
* @param ipRegionList
* @param strRegionList
* @param numRegionList
* @param digestRegionList
* @param areaIpRegionList
* @param userRegion
*/
public static String configCovert(List<IpPortCfg> ipList,List<BaseStringCfg> strList,List<ComplexkeywordCfg> complexStrList,
List<com.nis.domain.configuration.NumBoundaryCfg > numList,
List<FileDigestCfg> fileList,List<Integer> regionIds,List<Integer> groupIds,BaseCfg entity,
Integer compileId,Date auditTime,List<GroupCfg> groupRelationList,
List<IpCfg> ipRegionList,
List<StringCfg> strRegionList,
List<NumBoundaryCfg> numRegionList,
List<DigestCfg> digestRegionList,
List<IpCfg> areaIpRegionList,String userRegion){
List list1 = new ArrayList();
List<BaseStringCfg> list2 = new ArrayList();
List<ComplexkeywordCfg> list3 = new ArrayList();
List<com.nis.domain.configuration.NumBoundaryCfg> list4 = new ArrayList();
List<FileDigestCfg> list5 = new ArrayList();
if(ipList.size()>0){
for(int index=0;index<ipList.size();index++){
IpPortCfg ip = ipList.get(index);
if(ip.getCompileId().equals(compileId)){
ip.setRegionId(regionIds.get(0));
regionIds.remove(0);
ip.setGroupId(groupIds.get(0));
groupIds.remove(0);
ip.setIsValid(entity.getIsValid());
ip.setAuditTime(auditTime);
list1.add(ip);
}
}
}
for(int index=0;index<strList.size();index++){
BaseStringCfg str = strList.get(index);
if(str.getCompileId().equals(compileId)){
str.setRegionId(regionIds.get(0));
regionIds.remove(0);
str.setGroupId(groupIds.get(0));
groupIds.remove(0);
str.setIsValid(entity.getIsValid());
str.setAuditTime(auditTime);
list2.add(str);
if(entity.getServiceId().equals(513)||entity.getServiceId().equals(515)){
if(userRegion.equals("")){
userRegion += Constants.USERREGION_DOMAIN_STR+"="+str.getCfgKeywords();
}else{
userRegion += Constants.USER_REGION_SPLIT+Constants.USERREGION_DOMAIN_STR+"="+str.getCfgKeywords();
}
}
}
}
for(int index=0;index<complexStrList.size();index++){
ComplexkeywordCfg str = complexStrList.get(index);
if(str.getCompileId().equals(compileId)){
str.setRegionId(regionIds.get(0));
regionIds.remove(0);
str.setGroupId(groupIds.get(0));
groupIds.remove(0);
str.setIsValid(entity.getIsValid());
str.setAuditTime(auditTime);
list3.add(str);
if(entity.getServiceId().equals(129) && str.getDistrict()!=null){//http监测
String dictValue = DictUtils.getDictCode(Constants.HTTP_HEADER_DICT_MODULE, str.getDistrict());
if(StringUtil.isEmpty(dictValue) || dictValue.equals("默认")){
if(userRegion.equals("")){
userRegion += Constants.HTTP_HEADER_USER_REGION_KEY+"="+str.getDistrict();
}else{
userRegion += Constants.USER_REGION_SPLIT+Constants.HTTP_HEADER_USER_REGION_KEY+"="+str.getDistrict();
}
}
}
}
}
for(int index=0;index<numList.size();index++){
com.nis.domain.configuration.NumBoundaryCfg num = numList.get(index);
if(num.getCompileId().equals(compileId)){
num.setRegionId(regionIds.get(0));
regionIds.remove(0);
num.setGroupId(groupIds.get(0));
groupIds.remove(0);
num.setIsValid(entity.getIsValid());
num.setAuditTime(auditTime);
list4.add(num);
}
}
for(int index=0;index<fileList.size();index++){
FileDigestCfg file = fileList.get(index);
if(file.getCompileId().equals(compileId)){
file.setRegionId(regionIds.get(0));
regionIds.remove(0);
file.setGroupId(groupIds.get(0));
groupIds.remove(0);
file.setIsValid(entity.getIsValid());
file.setAuditTime(auditTime);
list5.add(file);
}
}
if(list1.size()>0){
ipList.removeAll(list1);
Map<String,List> map = cfgToMaatConvert(ipRegionList,list1,1,groupRelationList);
groupRelationList=map.get("groupList");
ipRegionList=map.get("dstList");
if(map.get("numRegionList")!=null){
numRegionList.addAll(map.get("numRegionList"));
}
}
if(list2.size()>0){
strList.removeAll(list2);
Map<String,List> map = cfgToMaatConvert(strRegionList,list2,2,groupRelationList);
groupRelationList=map.get("groupList");
strRegionList=map.get("dstList");
}
if(list3.size()>0){
complexStrList.removeAll(list3);
Map<String,List> map = cfgToMaatConvert(strRegionList,list3,3,groupRelationList);
groupRelationList=map.get("groupList");
strRegionList=map.get("dstList");
}
if(list4.size()>0){
numList.removeAll(list4);
Map<String,List> map = cfgToMaatConvert(numRegionList,list4,4,groupRelationList);
groupRelationList=map.get("groupList");
numRegionList=map.get("dstList");
}
if(list5.size()>0){
fileList.removeAll(list5);
Map<String,List> map = cfgToMaatConvert(digestRegionList,list5,5,groupRelationList);
groupRelationList=map.get("groupList");
digestRegionList=map.get("dstList");
}
return userRegion;
}
// asn IP 复用转换
public static List<IpCfg> groupReuseCfgAddRemoveConvert(List<? extends BaseCfg<?>> ipCfgList, Integer isValid,
Integer groupId) {
logger.warn("convert data start");
long start = System.currentTimeMillis();
Date opTime = new Date();
List<IpCfg> maatIpList = new ArrayList<>();
if (ipCfgList.size() > 0) {
// 只用一次instanceof,取代循环中每次都用一次instanceof
if (ipCfgList.get(0) instanceof AsnIpCfg) {
for (BaseCfg<?> _cfg : ipCfgList) {
IpCfg cfg = new IpCfg();
BaseIpCfg baseIpCfg = new BaseIpCfg();
AsnIpCfg asnIpCfg = (AsnIpCfg) _cfg;
BeanUtils.copyProperties(asnIpCfg, baseIpCfg);
BeanUtils.copyProperties(baseIpCfg, cfg);
cfg.setGroupId(asnIpCfg.getAsnIpGroup());
cfg.setRegionId(asnIpCfg.getRegionId());
String userRegion = "ASN_ID=" + asnIpCfg.getUserRegion1();
cfg.setUserRegion(userRegion);
cfg.setIsValid(isValid);
cfg.setAuditTime(opTime);
List<IpCfg> cfgs = ipConvert(cfg, baseIpCfg);
maatIpList.addAll(cfgs);
}
} else if (ipCfgList.get(0) instanceof AppIpCfg) {
for (BaseCfg<?> _cfg : ipCfgList) {
IpCfg cfg = new IpCfg();
BaseIpCfg baseIpCfg = new BaseIpCfg();
AppIpCfg appIpCfg = (AppIpCfg) _cfg;
BeanUtils.copyProperties(appIpCfg, baseIpCfg);
BeanUtils.copyProperties(baseIpCfg, cfg);
cfg.setGroupId(groupId);
cfg.setRegionId(Integer.parseInt(appIpCfg.getUserRegion1()));
String userRegion = "APP_ID=" + appIpCfg.getAppCode();
cfg.setUserRegion(userRegion);
cfg.setIsValid(isValid);
cfg.setAuditTime(opTime);
List<IpCfg> cfgs = ipConvert(cfg, baseIpCfg);
maatIpList.addAll(cfgs);
}
}
}
long end = System.currentTimeMillis();
logger.warn("convert data finish,cost:" + (end - start));
return maatIpList;
}
/**
* 界面配置list转换为服务接口端的list用于批量下发时regionId,groupId已在该方法前被批量获取
*
* @param <T>
* @param <T>
* @param dstList
* @param srcList
* @param cfgType1为IP类型2为字符串类型3为增强字符串4数值类型5摘要类,6回调类[但字符串类域配置和增强字符串域配置在接口参数中同属于strRegionList]
* @param baseCfg配置基本信息
* @param groupRelationList
* 配置分组列表
* @return
*/
public static <T> Map<String, List> cfgToMaatConvert(List dstList, List<T> srcList, Integer cfgType,List groupRelationList) {
Map<String, List> map = new HashMap();
if (cfgType == 1) {
List numRegionList = new ArrayList();
Integer groupId = 0;
Integer numGroupId = 0;
for (int i = 0; i < srcList.size(); i++) {
List<Integer> regionIdList = Lists.newArrayList();
T srcCfg = srcList.get(i);
BaseIpCfg baseIpCfg = new BaseIpCfg();
BeanUtils.copyProperties(srcCfg, baseIpCfg);
regionIdList.add(baseIpCfg.getRegionId());
IpCfg cfg = new IpCfg();
BeanUtils.copyProperties(baseIpCfg, cfg);
//多条IP配置属于同一个分组
if (groupId == 0) {
GroupCfg group = new GroupCfg();
groupId = baseIpCfg.getGroupId();
group.setGroupId(groupId);
group.setCompileId(baseIpCfg.getCompileId());
group.setAuditTime(baseIpCfg.getAuditTime());
group.setIsValid(baseIpCfg.getIsValid());
groupRelationList.add(group);
}
cfg.setGroupId(groupId);
cfg.setAuditTime(baseIpCfg.getAuditTime());
cfg.setIsValid(baseIpCfg.getIsValid());
List<IpCfg> cfgs = ipConvert(cfg, baseIpCfg);
if (cfgs.size() > 1) {
List<Integer> ids = ConfigServiceUtil.getId(3, cfgs.size() - 1);
regionIdList.addAll(ids);
}
for (int j = i; j < cfgs.size() + i; j++) {
cfgs.get(j - i).setRegionId(regionIdList.get(j));
}
dstList.addAll(cfgs);
// 如果protocolId非空非零需要构造数值型域配置多条相同协议的IP只需要一条数值域配置目前没有不同协议IP&情况)
if (baseIpCfg.getProtocolId() != null && baseIpCfg.getProtocolId() != 0) {
if (numGroupId == 0) {
GroupCfg group1 = new GroupCfg();
group1.setGroupId(ConfigServiceUtil.getId(2, 1).get(0));
group1.setCompileId(baseIpCfg.getCompileId());
group1.setAuditTime(baseIpCfg.getAuditTime());
group1.setIsValid(baseIpCfg.getIsValid());
groupRelationList.add(group1);
NumBoundaryCfg numCfg = new NumBoundaryCfg();
numCfg.initDefaultValue();
numCfg.setLowBoundary(baseIpCfg.getProtocolId());
numCfg.setUpBoundary(baseIpCfg.getProtocolId());
numCfg.setRegionId(ConfigServiceUtil.getId(3, 1).get(0));
numCfg.setAuditTime(baseIpCfg.getAuditTime());
numCfg.setGroupId(group1.getGroupId());
numCfg.setIsValid(baseIpCfg.getIsValid());
numRegionList.add(numCfg);
map.put("numRegionList", numRegionList);
numGroupId++;
}
}
}
} else if (cfgType == 2 || cfgType == 3) {
for (int i = 0; i < srcList.size(); i++) {
// 一条业务配置创建一个分组
BaseCfg baseCfg = new BaseCfg();
BeanUtils.copyProperties(srcList.get(i), baseCfg,new String[]{"menuNameCode"});//拷贝公共属性
GroupCfg group = new GroupCfg();
StringCfg cfg = new StringCfg();
BeanUtils.copyProperties(srcList.get(i), cfg,new String[]{"menuNameCode"});//拷贝公共属性以及私有属性
group.setGroupId(baseCfg.getGroupId());
group.setCompileId(baseCfg.getCompileId());
group.setAuditTime(baseCfg.getAuditTime());
group.setIsValid(baseCfg.getIsValid());
groupRelationList.add(group);
cfg.setGroupId(group.getGroupId());
cfg.setRegionId(baseCfg.getRegionId());
cfg.setAuditTime(baseCfg.getAuditTime());
cfg.setIsValid(baseCfg.getIsValid());
// 处理配置关键字转译
cfg.setCfgKeywords(keywordsEscape(cfg.getCfgKeywords()));
// 增强字符串转换
cfg.setDistrict(keywordsEscape(cfg.getDistrict()));
dstList.add(cfg);
}
} else if (cfgType == 4) {
for (int i = 0; i < srcList.size(); i++) {
BaseCfg baseCfg = new BaseCfg();
BeanUtils.copyProperties(srcList.get(i), baseCfg);//拷贝公共属性
// 一条业务配置创建一个分组
com.nis.domain.maat.MaatCfg.NumBoundaryCfg cfg = new com.nis.domain.maat.MaatCfg.NumBoundaryCfg();
BeanUtils.copyProperties(srcList.get(i), cfg);
GroupCfg group = new GroupCfg();
group.setGroupId(baseCfg.getGroupId());
group.setCompileId(baseCfg.getCompileId());
group.setAuditTime(baseCfg.getAuditTime());
group.setIsValid(baseCfg.getIsValid());
groupRelationList.add(group);
cfg.setGroupId(group.getGroupId());
cfg.setRegionId(baseCfg.getRegionId());
cfg.setAuditTime(baseCfg.getAuditTime());
cfg.setIsValid(baseCfg.getIsValid());
dstList.add(cfg);
}
} else if (cfgType == 5) {
for (int i = 0; i < srcList.size(); i++) {
BaseCfg baseCfg = new BaseCfg();
BeanUtils.copyProperties(srcList.get(i), baseCfg);//拷贝公共属性
// 一条业务配置创建一个分组
com.nis.domain.maat.MaatCfg.DigestCfg cfg = new com.nis.domain.maat.MaatCfg.DigestCfg();
BeanUtils.copyProperties(srcList.get(i), cfg);
GroupCfg group = new GroupCfg();
group.setGroupId(baseCfg.getGroupId());
group.setCompileId(baseCfg.getCompileId());
group.setAuditTime(baseCfg.getAuditTime());
group.setIsValid(baseCfg.getIsValid());
groupRelationList.add(group);
cfg.setGroupId(group.getGroupId());
cfg.setRegionId(baseCfg.getRegionId());
cfg.setAuditTime(baseCfg.getAuditTime());
cfg.setIsValid(baseCfg.getIsValid());
dstList.add(cfg);
}
} else {
dstList.addAll(srcList);
}
map.put("groupList", groupRelationList);
map.put("dstList", dstList);
return map;
}
/**
* 关键字特殊字符转义处理
* @param cfgKeywords
* @return
*/
public static String keywordsEscape(String cfgKeywords) {
if (StringUtils.isNotEmpty(cfgKeywords)) {
// 不转译特殊字符
cfgKeywords = cfgKeywords.trim();// 首先去掉首尾空格
cfgKeywords = StringEscapeUtils.unescapeHtml4(cfgKeywords);
cfgKeywords = cfgKeywords.replace("\\", "\\\\");
cfgKeywords = cfgKeywords.replace("&", "\\&");
cfgKeywords = cfgKeywords.replace(" ", "\\b");
// ***and***在界面表示多个关键字的与表达式此特殊字符串在common.js中使用定义maat端以&表示
cfgKeywords = cfgKeywords.replace(Constants.KEYWORD_EXPR, "&");
}
return cfgKeywords;
}
/**
* 界面IP配置转换为MAAT类或者回调类IP配置
*
* @param dstIp
* @param srcIp
* @return
*/
public static List<IpCfg> ipConvert(IpCfg dstIp, BaseIpCfg srcIp) {
List<IpCfg> ipConvertList = Lists.newArrayList();
boolean isRange = ((srcIp.getIpPattern() != null && srcIp.getIpPattern() == 2)
|| (srcIp.getSrcIpAddress() != null && srcIp.getSrcIpAddress().indexOf("-") > -1)
|| (srcIp.getDestIpAddress() != null && srcIp.getDestIpAddress().indexOf("-") > -1));
if (isRange) {
List<IpCfg> tempList = Lists.newArrayList();
List<IpCfg> tempList1 = Lists.newArrayList();
if (srcIp.getIpType().intValue() == 4) {
if (srcIp.getSrcIpAddress() != null) {
String startIpPart = srcIp.getSrcIpAddress().split("-")[0];
String endIpPart = srcIp.getSrcIpAddress().split("-")[1];
Integer startNum = Integer.parseInt(startIpPart.split("\\.")[3]);
Integer endNum = Integer.parseInt(endIpPart.split("\\.")[3]);
for (int i = startNum; i <= endNum; i++) {
IpCfg tempIp = new IpCfg();
BeanUtils.copyProperties(dstIp, tempIp);
tempIp.setSrcIp(startIpPart.substring(0, startIpPart.lastIndexOf(".") + 1) + i);
tempIp.setSrcIpMask("255.255.255.255");
tempList.add(tempIp);
}
} else {
dstIp.setSrcIp("0.0.0.0");
dstIp.setSrcIpMask("255.255.255.255");
tempList.add(dstIp);
}
if (srcIp.getDestIpAddress() != null) {
String startIpPart = srcIp.getDestIpAddress().split("-")[0];
String endIpPart = srcIp.getDestIpAddress().split("-")[1];
Integer startNum = Integer.parseInt(startIpPart.split("\\.")[3]);
Integer endNum = Integer.parseInt(endIpPart.split("\\.")[3]);
for (IpCfg _cfg : tempList) {
for (int i = startNum; i <= endNum; i++) {
IpCfg tempIp = new IpCfg();
BeanUtils.copyProperties(_cfg, tempIp);
tempIp.setDstIp(startIpPart.substring(0, startIpPart.lastIndexOf(".") + 1) + i);
tempIp.setDstIpMask("255.255.255.255");
// 处理
convertPortValues(tempIp, srcIp);
if (!tempIp.getSrcIp().equals(tempIp.getDstIp())) {
tempList1.add(tempIp);
}
}
}
tempList.clear();
} else {
for (IpCfg _cfg : tempList) {
_cfg.setDstIp("0.0.0.0");
_cfg.setSrcIpMask("255.255.255.255");
convertPortValues(_cfg, srcIp);
}
}
if (tempList1.size() > 0) {
ipConvertList.addAll(tempList1);
} else {
ipConvertList.addAll(tempList);
}
} else if (srcIp.getIpType().intValue() == 6) {
if (srcIp.getSrcIpAddress() != null) {
IPv6Address address1 = IPv6Address.fromString(srcIp.getSrcIpAddress().split("-")[0]);
IPv6Address address2 = IPv6Address.fromString(srcIp.getSrcIpAddress().split("-")[1]);
IPv6Network network = IPv6Network.fromTwoAddresses(address1, address2);
dstIp.setSrcIp(address1.toString());
dstIp.setSrcIpMask(network.getNetmask().asAddress().toString());
} else {
dstIp.setSrcIp("::");
dstIp.setSrcIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
}
if (srcIp.getDestIpAddress() != null) {
IPv6Address address1 = IPv6Address.fromString(srcIp.getDestIpAddress().split("-")[0]);
IPv6Address address2 = IPv6Address.fromString(srcIp.getDestIpAddress().split("-")[1]);
IPv6Network network = IPv6Network.fromTwoAddresses(address1, address2);
dstIp.setDstIp(address1.toString());
dstIp.setDstIpMask(network.getNetmask().asAddress().toString());
} else {
dstIp.setDstIp("::");
dstIp.setDstIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
}
ipConvertList.add(dstIp);
} else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
} else {
if (srcIp.getSrcIpAddress() != null) {
if (srcIp.getSrcIpAddress().indexOf("/") != -1) {
if (srcIp.getIpType() == 4 /* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
Integer srcMaskNum = Integer.parseInt(srcIp.getSrcIpAddress().split("/")[1]);
if (srcMaskNum == 0) {
dstIp.setSrcIpMask("0.0.0.0");
} else {
dstIp.setSrcIpMask(IpUtil.convertMask(srcMaskNum));
}
dstIp.setSrcIp(srcIp.getSrcIpAddress().split("/")[0]);
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
IPv6Network strangeNetwork = IPv6Network.fromString(srcIp.getSrcIpAddress());
dstIp.setSrcIp(srcIp.getSrcIpAddress().split("/")[0]);
dstIp.setSrcIpMask(strangeNetwork.getNetmask().asAddress().toString());
} /*
* else { Pattern
* patternV4Subnet=Pattern.compile(Constants.IPV4_IP_SUBNET_REGEXP); Pattern
* patternV6Subnet=Pattern.compile(Constants.IPV6_IP_SUBNET_REGEXP); Matcher
* matchernV4Subnet=patternV4Subnet.matcher(srcIp.getSrcIpAddress()); Matcher
* matcherV6Subnet=patternV6Subnet.matcher(srcIp.getSrcIpAddress());
* if(matchernV4Subnet.matches()) { Integer srcMaskNum =
* Integer.parseInt(srcIp.getSrcIpAddress().split("/")[1]); if(srcMaskNum==0){
* dstIp.setSrcIpMask("0.0.0.0"); }else{
* dstIp.setSrcIpMask(IpUtil.convertMask(srcMaskNum)); }
* dstIp.setSrcIp(srcIp.getSrcIpAddress().split("/")[0]); }else
* if(matcherV6Subnet.matches()){ IPv6Network strangeNetwork =
* IPv6Network.fromString(srcIp.getSrcIpAddress());
* dstIp.setSrcIp(srcIp.getSrcIpAddress().split("/")[0]);
* dstIp.setSrcIpMask(strangeNetwork.getNetmask().asAddress().toString()); }else
* { throw new RuntimeException("Invalid IP/subnet mask format"); } }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
} else {
if (srcIp.getIpType() == 4/* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
dstIp.setSrcIp(srcIp.getSrcIpAddress());
dstIp.setSrcIpMask("255.255.255.255");
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
dstIp.setSrcIp(srcIp.getSrcIpAddress());
dstIp.setSrcIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
} /*
* else {//all Pattern patternV4=Pattern.compile(Constants.IPV4_IP_REGEXP);
* Pattern patternV6=Pattern.compile(Constants.IPV6_IP_REGEXP); Matcher
* matcherV4=patternV4.matcher(srcIp.getSrcIpAddress()); Matcher
* matcherV6=patternV6.matcher(srcIp.getSrcIpAddress()); if(matcherV4.matches())
* { dstIp.setSrcIp(srcIp.getSrcIpAddress());
* dstIp.setSrcIpMask("255.255.255.255"); }else if(matcherV6.matches()) {
* dstIp.setSrcIp(srcIp.getSrcIpAddress());
* dstIp.setSrcIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"); }else { throw
* new RuntimeException("Invalid IP format"); } }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
}
} else {
if (srcIp.getIpType() == 4/* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
dstIp.setSrcIp(srcIp.getSrcIpAddress());
dstIp.setSrcIpMask("255.255.255.255");
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
dstIp.setSrcIp(srcIp.getSrcIpAddress());
dstIp.setSrcIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
} /*
* else {//all dstIp.setSrcIp(srcIp.getSrcIpAddress());
* dstIp.setSrcIpMask("255.255.255.255"); }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
}
if (srcIp.getDestIpAddress() != null) {
if (srcIp.getDestIpAddress().indexOf("/") != -1) {
if (srcIp.getIpType() == 4/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
Integer dstMaskNum = Integer.parseInt(srcIp.getDestIpAddress().split("/")[1]);
if (dstMaskNum == 0) {
dstIp.setDstIpMask("0.0.0.0");
} else {
dstIp.setDstIpMask(IpUtil.convertMask(dstMaskNum));
;
}
dstIp.setDstIp(srcIp.getDestIpAddress().split("/")[0]);
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
IPv6Network strangeNetwork = IPv6Network.fromString(srcIp.getDestIpAddress());
dstIp.setDstIp(srcIp.getDestIpAddress().split("/")[0]);
dstIp.setDstIpMask(strangeNetwork.getNetmask().asAddress().toString());
} /*
* else { Pattern
* patternV4Subnet=Pattern.compile(Constants.IPV4_IP_SUBNET_REGEXP); Pattern
* patternV6Subnet=Pattern.compile(Constants.IPV6_IP_SUBNET_REGEXP); Matcher
* matchernV4Subnet=patternV4Subnet.matcher(srcIp.getDestIpAddress()); Matcher
* matcherV6Subnet=patternV6Subnet.matcher(srcIp.getDestIpAddress());
* if(matchernV4Subnet.matches()) { Integer dstMaskNum =
* Integer.parseInt(srcIp.getDestIpAddress().split("/")[1]); if(dstMaskNum==0){
* dstIp.setDstIpMask("0.0.0.0"); }else{
* dstIp.setDstIpMask(IpUtil.convertMask(dstMaskNum));; }
* dstIp.setDstIp(srcIp.getDestIpAddress().split("/")[0]); }else
* if(matcherV6Subnet.matches()){ IPv6Network strangeNetwork =
* IPv6Network.fromString(srcIp.getDestIpAddress());
* dstIp.setDstIp(srcIp.getDestIpAddress().split("/")[0]);
* dstIp.setDstIpMask(strangeNetwork.getNetmask().asAddress().toString()); }else
* { throw new RuntimeException("Invalid IP/subnet mask format"); } }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
} else {
if (srcIp.getIpType() == 4/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
dstIp.setDstIp(srcIp.getDestIpAddress());
dstIp.setDstIpMask("255.255.255.255");
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
dstIp.setDstIp(srcIp.getDestIpAddress());
dstIp.setDstIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
} /*
* else {//all Pattern patternV4=Pattern.compile(Constants.IPV4_IP_REGEXP);
* Pattern patternV6=Pattern.compile(Constants.IPV6_IP_REGEXP); Matcher
* matcherV4=patternV4.matcher(srcIp.getDestIpAddress()); Matcher
* matcherV6=patternV6.matcher(srcIp.getDestIpAddress());
* if(matcherV4.matches()) { dstIp.setDstIp(srcIp.getDestIpAddress());
* dstIp.setDstIpMask("255.255.255.255"); }else if(matcherV6.matches()) {
* dstIp.setDstIp(srcIp.getDestIpAddress());
* dstIp.setDstIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"); }else { throw
* new RuntimeException("invalid ip format"); } }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
}
} else {
if (srcIp.getIpType() == 4/* || srcIp.getIpType()==64 */) {// 64表示源ip为ipv6目的ip为ipv4
dstIp.setDstIp(srcIp.getDestIpAddress());
dstIp.setDstIpMask("255.255.255.255");
} else if (srcIp.getIpType() == 6/* || srcIp.getIpType()==46 */) {// 46表示源ip为ipv4目的ip为ipv6
dstIp.setDstIp(srcIp.getDestIpAddress());
dstIp.setDstIpMask("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
} /*
* else {//all dstIp.setDstIp(srcIp.getDestIpAddress());
* dstIp.setDstIpMask("255.255.255.255"); }
*/
else {
throw new RuntimeException("Unsupported IP type " + srcIp.getIpType());
}
}
if (srcIp.getSrcPort() != null) {
if (srcIp.getSrcPort().indexOf("/") != -1) {
String srcMaskNum = srcIp.getSrcPort().split("/")[1];
dstIp.setSrcPortMask(srcMaskNum);
dstIp.setSrcPort(srcIp.getSrcPort().split("/")[0]);
} else {
dstIp.setSrcPort(srcIp.getSrcPort());
dstIp.setSrcPortMask("65535");
}
} else {
dstIp.setSrcPort("0");
dstIp.setSrcPortMask("65535");
}
if (srcIp.getDestPort() != null) {
if (srcIp.getDestPort().indexOf("/") != -1) {
String dstMaskNum = srcIp.getDestPort().split("/")[1];
dstIp.setDstPortMask(dstMaskNum);
dstIp.setDstPort(srcIp.getDestPort().split("/")[0]);
} else {
dstIp.setDstPort(srcIp.getDestPort());
dstIp.setDstPortMask("65535");
}
} else {
dstIp.setDstPort("0");
dstIp.setDstPortMask("65535");
}
ipConvertList.add(dstIp);
}
return ipConvertList;
}
/**
* 设置端口值
*
* @param dstIp
* @param srcIp
*/
public static void convertPortValues(IpCfg dstIp, BaseIpCfg srcIp) {
if (srcIp.getSrcPort() != null) {
if (srcIp.getSrcPort().indexOf("/") != -1) {
String srcMaskNum = srcIp.getSrcPort().split("/")[1];
dstIp.setSrcPortMask(srcMaskNum);
dstIp.setSrcPort(srcIp.getSrcPort().split("/")[0]);
} else {
dstIp.setSrcPort(srcIp.getSrcPort());
dstIp.setSrcPortMask("65535");
}
} else {
dstIp.setSrcPort("0");
dstIp.setSrcPortMask("65535");
}
if (srcIp.getDestPort() != null) {
if (srcIp.getDestPort().indexOf("/") != -1) {
String dstMaskNum = srcIp.getDestPort().split("/")[1];
dstIp.setDstPortMask(dstMaskNum);
dstIp.setDstPort(srcIp.getDestPort().split("/")[0]);
} else {
dstIp.setDstPort(srcIp.getDestPort());
dstIp.setDstPortMask("65535");
}
} else {
dstIp.setDstPort("0");
dstIp.setDstPortMask("65535");
}
}
}

View File

@@ -819,4 +819,12 @@ public final class Constants {
* 流量日志的HTTP泛收接口URL
*/
public static final String NTC_HTTP_RECORD_LOG = Configurations.getStringProperty("ntcHttpRecordLog","");
/**
* 日期格式化
*/
public static final String COMMON_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 时间格式化
*/
public static final String COMMON_TIME_FORMAT = "HH:mm:ss";
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,66 @@
package com.nis.util;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import com.beust.jcommander.internal.Sets;
import com.nis.domain.FunctionServiceDict;
import jersey.repackaged.com.google.common.collect.Lists;
@SuppressWarnings("all")
public class ServiceConfigTemplateUtil {
private Logger logger = Logger.getLogger(getClass());
private static final Logger logger = Logger.getLogger(ServiceConfigTemplateUtil.class);
private Node root;
private static Node root;
static {
if(root == null) {//2018年12月28日11:37:50 fang 改为只加载一次,且方法改为 static
SAXReader reader = new SAXReader();
org.dom4j.Document document = null;
String configPath = "/service/service_config.xml";
InputStream is = null;
try {
is = ServiceConfigTemplateUtil.class.getResourceAsStream(configPath);
document = reader.read(is);
root = document.getRootElement();
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
} finally {
if(is != null ){
try {
is.close();
} catch (IOException e) { }
}
}
}
}
/**
* 配置文件内容
* @return
*/
public ServiceConfigTemplateUtil(){
SAXReader reader = new SAXReader();
org.dom4j.Document document = null;
String configPath = "/service/service_config.xml";
try {
document = reader.read(ServiceConfigTemplateUtil.class.getResourceAsStream(configPath));
root = document.getRootElement();
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
/**
* 获取业务节点列表
* @return
*/
public List<Node> getServiceNodeList(){
public static List<Node> getServiceNodeList(){
List<Node> nodes = root.selectNodes("service");
return nodes;
}
@@ -48,7 +68,7 @@ public class ServiceConfigTemplateUtil {
* 获取业务列表
* @return
*/
public List<Map<String,Object>> getServiceList(){
public static List<Map<String,Object>> getServiceList(){
List<Map<String,Object>> list =new ArrayList();
List<Element> elements = root.selectNodes("service");
for(Element element:elements){
@@ -63,12 +83,47 @@ public class ServiceConfigTemplateUtil {
}
return list;
}
/**
*
* @return
*/
public static Set<String> getCompileTableName(){
Set<String> result = Sets.newHashSet();
List<Element> elements = root.selectNodes("service");
for(Element element:elements){
String ev = element.attribute("tableName").getStringValue();
if(StringUtils.isNotBlank(ev)) {
result.add(ev.toLowerCase());
}
}
return result;
}
/**
* 根据类名 获取对应的 表名
* @param className
* @return
*/
public static String getCfgTableNameByClassName(String className) {
if(className == null) return null;
List<Element> elements = root.selectNodes("service");
for(Element element:elements){
String ev = element.attribute("tableName").getStringValue();
String cn = element.attribute("className").getStringValue();
if(className.equalsIgnoreCase(cn)) {
return ev.toLowerCase();
}
}
return null;
}
/**
*
* @param functionId
* @return
*/
public List<Map<String,Object>> getServiceListByFunctionId(Integer functionId){
public static List<Map<String,Object>> getServiceListByFunctionId(Integer functionId){
List<Map<String,Object>> list =new ArrayList();
if(!StringUtil.isEmpty(functionId)) {
List<FunctionServiceDict> serviceList = DictUtils.getFunctionServiceDictList(functionId);
@@ -133,7 +188,7 @@ public class ServiceConfigTemplateUtil {
* 获取业务配置列表
* @return
*/
public List<Map<String,Object>> getServiceCfgList(Element serviceNode){
public static List<Map<String,Object>> getServiceCfgList(Element serviceNode){
List<Map<String,Object>> list = new ArrayList();
List<Element> elements = serviceNode.selectNodes("serviceCfg");
for(Element element:elements){
@@ -149,7 +204,7 @@ public class ServiceConfigTemplateUtil {
* 获取用户自定义域列表
* @return
*/
public List<Map<String,Object>> getUserRegionList(Element serviceNode){
public static List<Map<String,Object>> getUserRegionList(Element serviceNode){
List<Map<String,Object>> list = new ArrayList();
List<Element> elements = serviceNode.selectNodes("userRegion");
for(Element element:elements){
@@ -167,7 +222,7 @@ public class ServiceConfigTemplateUtil {
* @param attribute
* @return
*/
public List getXmlParamListByTag(String tag,String attribute){
public static List getXmlParamListByTag(String tag,String attribute){
List list =new ArrayList();
List<Element> elements = root.selectNodes(tag);
for(Element element:elements){
@@ -196,6 +251,7 @@ public class ServiceConfigTemplateUtil {
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();

View File

@@ -0,0 +1,76 @@
package com.nis.web.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.nis.domain.ScheduleCfg;
import com.nis.domain.ScheduleExceInfo;
import com.nis.domain.configuration.BaseCfg;
@MyBatisDao
public interface SchedulerDao extends CrudDao<ScheduleCfg> {
List<ScheduleCfg> findScheduleList(ScheduleCfg cfg);
/**
* 查找最新的修改数据
* @param id
* @param size
* @return
*/
List<ScheduleCfg> findNewlyCfg(@Param("id")Long id,@Param("limit")Long limit);
/**
* 更新 del_flag 字段为删除标识
* @param cfg
* @return
*/
int deleteByCompileId(ScheduleCfg cfg);
/**
* 查找 配置 下发 最新记录
* @param compileId
* @param isValid
* @return
*/
ScheduleExceInfo findScheduleExceNew(ScheduleExceInfo se);
/**
* 修改配置表状态
* @param tableName
* @param compileId
* @param isValid
* @return
*/
int updateCfgTableStatus(@Param("tableName")String tableName,@Param("compileId")Integer compileId,@Param("isValid")Integer isValid);
/**
* 查询 配置信息
* @param compileId
* @return
*/
BaseCfg getCfgTableInfo(@Param("tableName")String tableName,@Param("compileId")Integer compileId);
/**
* 保存执行记录
* @param exceInfo
* @return
*/
int insertScheduleExceLog(ScheduleExceInfo exceInfo);
/**
* 保存最新记录表
* @param exceInfo
* @return
*/
int insertScheduleExceNew(ScheduleExceInfo exceInfo);
/**
* 更新最新记录表
* @param exceInfo
* @return
*/
int updateScheduleExceNew(ScheduleExceInfo exceInfo);
}

View File

@@ -0,0 +1,315 @@
<?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.nis.web.dao.SchedulerDao" >
<resultMap type="com.nis.domain.ScheduleCfg" id="scheduleCfgMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="cronValid" column="cron_valid"/>
<result property="cronInvalid" column="cron_invalid"/>
<result property="cfgId" column="cfg_id"/>
<result property="compileId" column="compile_id"/>
<result property="serviceId" column="service_id"/>
<result property="isValid" column="is_valid"/>
<result property="isAudit" column="is_audit"/>
<result property="functionId" column="function_id"/>
<result property="creatorId" column="creator_id"/>
<result property="createTime" column="create_time"/>
<result property="editorId" column="editor_id"/>
<result property="editTime" column="edit_time"/>
<result property="tableName" column="table_name"/>
<result property="userRegion1" column="user_region1"/>
<result property="userRegion2" column="user_region2"/>
<result property="userRegion3" column="user_region3"/>
<result property="userRegion4" column="user_region4"/>
<result property="userRegion5" column="user_region5"/>
<result property="delFlag" column="del_flag"/>
</resultMap>
<resultMap type="com.nis.domain.ScheduleExceInfo" id="scheduleExceInfoMap">
<id property="id" column="id"/>
<result property="scheduleId" column="schedule_id"/>
<result property="exceTime" column="exce_time"/>
<result property="issueStatus" column="issue_status"/>
<result property="issueResult" column="issue_result"/>
<result property="errorInfo" column="error_info"/>
<result property="compileId" column="compile_id"/>
<result property="isIssue" column="is_issue"/>
</resultMap>
<resultMap id="baseCfgMap" type="com.nis.domain.configuration.BaseCfg" >
<id column="cfg_id" property="cfgId" jdbcType="BIGINT" />
<result column="cfg_desc" property="cfgDesc" jdbcType="VARCHAR" />
<result column="action" property="action" jdbcType="INTEGER" />
<result column="is_valid" property="isValid" jdbcType="INTEGER" />
<result column="is_audit" property="isAudit" jdbcType="INTEGER" />
<result column="creator_id" property="creatorId" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="editor_id" property="editorId" jdbcType="INTEGER" />
<result column="edit_time" property="editTime" jdbcType="TIMESTAMP" />
<result column="auditor_id" property="auditorId" jdbcType="INTEGER" />
<result column="audit_time" property="auditTime" jdbcType="TIMESTAMP" />
<result column="service_id" property="serviceId" jdbcType="INTEGER" />
<result column="request_id" property="requestId" jdbcType="INTEGER" />
<result column="compile_id" property="compileId" jdbcType="INTEGER" />
<result column="is_area_effective" property="isAreaEffective" jdbcType="INTEGER" />
<result column="classify" property="classify" jdbcType="VARCHAR" />
<result column="attribute" property="attribute" jdbcType="VARCHAR" />
<result column="lable" property="lable" jdbcType="VARCHAR" />
<result column="area_effective_ids" property="areaEffectiveIds" jdbcType="VARCHAR" />
<result column="function_id" property="functionId" jdbcType="INTEGER" />
<result column="do_log" property="doLog" jdbcType="INTEGER" />
<result column="do_blacklist" property="doBlackList" jdbcType="INTEGER" />
</resultMap>
<sql id="scheduleCfgColumns">
a.ID,
a.NAME,
a.cron_valid,
a.cron_invalid,
a.SERVICE_ID,
a.COMPILE_ID,
a.CFG_ID,
a.IS_VALID,
a.IS_AUDIT,
a.function_id,
a.CREATOR_ID,
a.CREATE_TIME,
a.EDITOR_ID,
a.EDIT_TIME,
a.table_name,
a.user_region1,
a.user_region2,
a.user_region3,
a.user_region4,
a.user_region5
</sql>
<select id="findScheduleList" resultMap="scheduleCfgMap">
select
<include refid="scheduleCfgColumns"/>
from schedule_cfg a
<where>
del_Flag = #{DEL_FLAG_NORMAL}
<if test="id != null">
and id = #{id}
</if>
<if test="compileId != null">
and compile_id = #{compileId}
</if>
<if test="isValid != null">
and IS_VALID = #{isValid}
</if>
<if test="isAudit != null">
and IS_AUDIT = #{isAudit}
</if>
<if test="compileId != null">
and CFG_ID = #{cfgId}
</if>
<if test="functionId != null">
and function_id = #{functionId}
</if>
<if test="tableName != null and tableName != ''">
and table_name = #{tableName}
</if>
<!-- 动态where条件 -->
<if test=" whereStr != null and whereStr !=''">
${whereStr}
</if>
</where>
order by a.id
</select>
<!-- 查找最新的更新数据 -->
<select id="findNewlyCfg" resultMap="scheduleCfgMap">
select
a.ID,
a.NAME,
a.cron_valid,
a.cron_invalid,
a.SERVICE_ID,
a.COMPILE_ID,
a.CFG_ID,
a.IS_VALID,
a.IS_AUDIT,
a.CREATOR_ID,
a.CREATE_TIME,
a.EDITOR_ID,
a.EDIT_TIME,
a.table_name,
a.user_region1,
a.user_region2,
a.user_region3,
a.user_region4,
a.user_region5
from schedule_cfg a
<where>
del_Flag = 1
and id > #{id}
</where>
order by a.id
limit #{limit}
</select>
<insert id="insert" parameterType="com.nis.domain.ScheduleCfg" useGeneratedKeys="true" keyProperty="id" >
insert into schedule_cfg (
NAME,
cron_valid,
cron_invalid,
SERVICE_ID,
COMPILE_ID,
CFG_ID,
IS_VALID,
IS_AUDIT,
function_id,
CREATOR_ID,
CREATE_TIME,
EDITOR_ID,
EDIT_TIME,
table_name,
user_region1,
user_region2,
user_region3,
user_region4,
user_region5
) values (
#{name,jdbcType=VARCHAR},
#{cronValid,jdbcType=VARCHAR},
#{cronInvalid,jdbcType=VARCHAR},
#{serviceId,jdbcType=INTEGER},
#{compileId,jdbcType=INTEGER},
#{cfgId,jdbcType=INTEGER},
#{isValid,jdbcType=INTEGER},
#{isAudit,jdbcType=INTEGER},
#{functionId,jdbcType=INTEGER},
#{creatorId,jdbcType=INTEGER},
#{createTime,jdbcType=TIMESTAMP},
#{editorId,jdbcType=INTEGER},
#{editTime,jdbcType=TIMESTAMP},
#{tableName,jdbcType=VARCHAR},
#{userRegion1,jdbcType=VARCHAR},
#{userRegion2,jdbcType=VARCHAR},
#{userRegion3,jdbcType=VARCHAR},
#{userRegion4,jdbcType=VARCHAR},
#{userRegion5,jdbcType=VARCHAR}
)
</insert>
<!-- 根据 compileId 将定时任务失效,定时任务的修改策略为:删除之前的所有配置,新增 -->
<update id="deleteByCompileId" parameterType="com.nis.domain.ScheduleCfg">
update schedule_cfg
<set>
<if test="editorId != null ">
editor_Id = #{editorId,jdbcType=VARCHAR},
</if>
<if test="editTime != null ">
edit_Time = #{editTime,jdbcType=TIMESTAMP},
</if>
del_flag = #{DEL_FLAG_DELETE}
</set>
WHERE compile_Id = #{compileId} and del_flag =1
</update>
<!-- 查找 配置 下发 最新记录 -->
<select id="findScheduleExceNew" resultMap="scheduleExceInfoMap" >
SELECT
id,
schedule_id,
exce_time,
issue_status,
issue_result,
error_info,
compile_id,
is_issue
FROM
schedule_exce_new
WHERE
compile_id = #{compileId} and issue_status = #{isValid}
</select>
<!-- 修改配置表状态 -->
<update id="updateCfgTableStatus">
update ${tableName} set is_valid = #{isValid} ,is_audit = 1 where compile_id = #{compileId}
</update>
<!-- 查询最新的配置状态 -->
<select id="getCfgTableInfo" resultMap="baseCfgMap">
select * from ${tableName} where compile_id = #{compileId};
</select>
<!-- 保存执行记录 -->
<insert id="insertScheduleExceLog" parameterType="com.nis.domain.ScheduleExceInfo">
INSERT INTO schedule_exce_log (
schedule_id,
exce_time,
issue_status,
issue_result,
error_info,
compile_id,
is_issue
) VALUES (
#{scheduleId},
#{exceTime},
#{issueStatus},
#{issueResult},
#{errorInfo},
#{compileId},
0
);
</insert>
<!-- 保存最新记录表 -->
<insert id="insertScheduleExceNew" parameterType="com.nis.domain.ScheduleExceInfo">
INSERT INTO schedule_exce_new (
schedule_id,
exce_time,
issue_status,
issue_result,
error_info,
compile_id,
is_issue
) VALUES (
#{scheduleId},
#{exceTime},
#{issueStatus},
#{issueResult},
#{errorInfo},
#{compileId},
0
);
</insert>
<!-- 更新最新记录表 -->
<update id="updateScheduleExceNew" parameterType="com.nis.domain.ScheduleExceInfo">
UPDATE schedule_exce_new
<set>
<if test="scheduleId != null">
schedule_id = #{scheduleId},
</if>
<if test=" exceTime != null">
exce_time = #{exceTime},
</if>
<if test=" issueResult != null">
issue_result = #{issueResult},
</if>
<if test=" errorInfo != null">
error_info = #{errorInfo},
</if>
<if test=" isIssue != null">
is_issue = #{isIssue},
</if>
</set>
WHERE
compile_Id = #{compileId} and issue_status = #{issueStatus}
</update>
</mapper>

View File

@@ -99,4 +99,6 @@ public interface ConfigSynchronizationDao {
public List<AppIpCfg> getAppIpFeatureList(BaseCfg entity);
public void updateCfgStatus(BaseCfg entity);
public PxyObjSpoofingIpPool getPxyObjSpoofingIpPool(Long cfgId);
}

View File

@@ -733,6 +733,39 @@
<result column="dns_strategy_id" property="dnsStrategyId" jdbcType="INTEGER" />
<result column="dns_strategy_name" property="dnsStrategyName" jdbcType="VARCHAR" />
</resultMap>
<resultMap id="PxyObjSpoofingPoolMap" type="com.nis.domain.configuration.PxyObjSpoofingIpPool" >
<id column="cfg_id" property="cfgId" jdbcType="BIGINT" />
<result column="cfg_desc" property="cfgDesc" jdbcType="VARCHAR" />
<result column="cfg_region_code" property="cfgRegionCode" jdbcType="INTEGER" />
<result column="ip_type" property="ipType" jdbcType="INTEGER" />
<result column="ip_address" property="ipAddress" jdbcType="VARCHAR" />
<result column="direction" property="direction" jdbcType="INTEGER" />
<result column="protocol" property="protocol" jdbcType="INTEGER" />
<result column="location" property="location" jdbcType="INTEGER" />
<result column="port" property="port" jdbcType="VARCHAR" />
<!-- <result column="action" property="action" jdbcType="INTEGER" /> -->
<result column="is_valid" property="isValid" jdbcType="INTEGER" />
<result column="is_audit" property="isAudit" jdbcType="INTEGER" />
<result column="creator_id" property="creatorId" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="editor_id" property="editorId" jdbcType="INTEGER" />
<result column="edit_time" property="editTime" jdbcType="TIMESTAMP" />
<result column="auditor_id" property="auditorId" jdbcType="INTEGER" />
<result column="audit_time" property="auditTime" jdbcType="TIMESTAMP" />
<result column="service_id" property="serviceId" jdbcType="INTEGER" />
<result column="request_id" property="requestId" jdbcType="INTEGER" />
<result column="compile_id" property="compileId" jdbcType="INTEGER" />
<result column="location" property="location" jdbcType="INTEGER"/>
<result column="is_area_effective" property="isAreaEffective" jdbcType="INTEGER" />
<result column="classify" property="classify" jdbcType="VARCHAR" />
<result column="attribute" property="attribute" jdbcType="VARCHAR" />
<result column="lable" property="lable" jdbcType="VARCHAR" />
<result column="area_effective_ids" property="areaEffectiveIds" jdbcType="VARCHAR" />
<result column="function_id" property="functionId" jdbcType="INTEGER" />
<result column="group_id" property="groupId" jdbcType="INTEGER" />
<result column="group_name" property="groupName" jdbcType="INTEGER" />
<result column="user_region" property="userRegion" jdbcType="VARCHAR" />
</resultMap>
<sql id="BaseCfg_Column" >
a.cfg_id,a.cfg_desc,a.action,a.is_valid,a.is_audit,a.creator_id,a.audit_time,
a.service_id,a.request_id,a.compile_id,a.is_area_effective,a.classify,a.attribute,a.lable,
@@ -877,12 +910,13 @@
a.ip_type,a.src_ip_address,a.ip_pattern,a.port_pattern,a.src_port
,a.protocol,a.direction,a.dest_port,a.dest_ip_address,a.cfg_type,a.compile_id
</sql>
<sql id="PxyObjSpoofingIpPoolColumns">
a.CFG_ID, a.CFG_DESC,a.CFG_REGION_CODE, a.IP_TYPE, a.IP_ADDRESS,
a.DIRECTION,a.PROTOCOL,a.IS_VALID,a.IS_AUDIT,a.location,a.port,
a.CREATOR_ID,a.CREATE_TIME,a.EDITOR_ID,a.EDIT_TIME,a.AUDITOR_ID,a.AUDIT_TIME,
a.SERVICE_ID,a.REQUEST_ID,a.COMPILE_ID,a.IS_AREA_EFFECTIVE,a.CLASSIFY,
a.ATTRIBUTE,a.LABLE,a.AREA_EFFECTIVE_IDS,a.FUNCTION_ID,a.GROUP_ID,a.user_region
<sql id="PxyObjSpoofingIpPoolColumns">
r.CFG_ID, r.CFG_DESC,r.CFG_REGION_CODE, r.IP_TYPE, r.IP_ADDRESS,
r.DIRECTION,r.PROTOCOL,r.IS_VALID,r.IS_AUDIT,r.location,r.port,
r.CREATOR_ID,r.CREATE_TIME,r.EDITOR_ID,r.EDIT_TIME,r.AUDITOR_ID,r.AUDIT_TIME,
r.SERVICE_ID,r.REQUEST_ID,r.COMPILE_ID,r.IS_AREA_EFFECTIVE,r.CLASSIFY,
r.ATTRIBUTE,r.LABLE,r.AREA_EFFECTIVE_IDS,r.FUNCTION_ID,r.GROUP_ID,r.user_region
</sql>
<!-- <sql id="WebsiteDomainTopic_Column">
id,website_service_id websiteServiceId,domain,topic_id topicId,create_time createTime,creator_id creatorId,is_valid isValid
@@ -938,7 +972,16 @@
<if test="action != null">
AND a.action=#{action,jdbcType=INTEGER}
</if>
and a.is_valid=#{isValid} and a.is_audit=#{isAudit} and a.is_valid!=-1
<if test="isValid != null">
AND a.is_valid=#{isValid,jdbcType=INTEGER}
</if>
<if test="isAudit != null">
AND a.is_audit=#{isAudit,jdbcType=INTEGER}
</if>
<if test="compileId != null">
AND a.compile_id=#{compileId,jdbcType=INTEGER}
</if>
and a.is_valid!=-1
</trim>
ORDER BY a.CFG_ID
</select>
@@ -961,7 +1004,16 @@
<if test="action != null">
AND a.action=#{action,jdbcType=INTEGER}
</if>
and a.is_valid=#{isValid} and a.is_audit=#{isAudit} and a.is_valid!=-1
<if test="isValid != null">
AND a.is_valid=#{isValid,jdbcType=INTEGER}
</if>
<if test="isAudit != null">
AND a.is_audit=#{isAudit,jdbcType=INTEGER}
</if>
<if test="compileId != null">
AND a.compile_id=#{compileId,jdbcType=INTEGER}
</if>
and a.is_valid!=-1
</trim>
ORDER BY a.CFG_ID
</select>
@@ -1602,6 +1654,13 @@
and function_id=#{functionId,jdbcType=INTEGER}
</trim>
</update>
<select id="getPxyObjSpoofingIpPool" resultMap="PxyObjSpoofingPoolMap" >
SELECT
<include refid="PxyObjSpoofingIpPoolColumns"/>
FROM pxy_obj_spoofing_ip_pool r
where r.CFG_ID=#{cfgId,jdbcType=BIGINT}
</select>
<!-- <select id="findAppPolicyList" resultMap="AppPolicyCfgMap" parameterType="com.nis.domain.configuration.AppPolicyCfg" >
select
<include refid="AppPolicyCfg_Column"/>

View File

@@ -0,0 +1,116 @@
package com.nis.web.service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.nis.domain.ScheduleCfg;
import com.nis.domain.ScheduleExceInfo;
import com.nis.domain.configuration.BaseCfg;
import com.nis.util.SchedulerTaskUtil;
import com.nis.util.ServiceConfigTemplateUtil;
import com.nis.web.dao.SchedulerDao;
import com.nis.web.dao.configuration.ConfigSynchronizationDao;
@Service
public class ScheduleService extends BaseService{
@Autowired
private SchedulerDao dao ;
@Autowired
private ConfigSynchronizationDao configSynchronizationDao;
@SuppressWarnings("rawtypes")
@Transactional(readOnly=false,rollbackFor=RuntimeException.class)
public void issueCompileInfo(ScheduleCfg cfg,Integer isValid) {
Integer compileId = cfg.getCompileId();
BaseCfg baseCfg = dao.getCfgTableInfo(cfg.getTableName(),compileId);//查询当前配置的最新状态
Integer curIsValid = baseCfg.getIsValid();//当前配置的最新 是否有效信息
if(curIsValid == isValid) {
logger.info(String.format("当前isValid状态没有变化,不需执行,compileId:%s,isValid : %s", compileId,isValid));
return;
}
//1、根据 compileId isvalid 查找new 判断是否已经下发过
ScheduleExceInfo se = new ScheduleExceInfo();
se.setCompileId(compileId);
se.setIsValid(isValid);
ScheduleExceInfo exceNew = dao.findScheduleExceNew(se);
//2、如果已经下发直接下发状态否则下发配置
Integer issueResult = 1;
String errorInfo = null;
String tableName = cfg.getTableName();
SchedulerTaskUtil scheduler = new SchedulerTaskUtil();
boolean udpateConfigStatus = false;
try {
if(isValid == 1 && (exceNew == null || exceNew.getIsIssue() == 1)) {//生效配置需要下发
udpateConfigStatus = scheduler.updateConfigByServiceAndCompile(cfg.getServiceId(), compileId, isValid, 1,configSynchronizationDao);
logger.info(String.format("定时器下发配置内容compileId:%s,isValid:%s,issueResult:%s,errorInfo:%s",compileId,isValid,issueResult,errorInfo));
}else{//只需修改状态
udpateConfigStatus = scheduler.updateConfigByServiceAndCompile(cfg.getServiceId(), compileId, isValid, 0,configSynchronizationDao);
logger.info(String.format("定时器修改配置状态compileId:%s,isValid:%s,issueResult:%s,errorInfo:%s",compileId,isValid,issueResult,errorInfo));
}
} catch (NoSuchFieldException e) {
udpateConfigStatus = false;
e.printStackTrace();
} catch (SecurityException e) {
udpateConfigStatus = false;
e.printStackTrace();
} catch (IllegalArgumentException e) {
udpateConfigStatus = false;
e.printStackTrace();
} catch (IllegalAccessException e) {
udpateConfigStatus = false;
e.printStackTrace();
}
// logger.info(String.format("配置状态更新compileId:%s,isValid:%s,issueResult:%s,errorInfo:%s",compileId,isValid,issueResult,errorInfo));
if(udpateConfigStatus){//配置更新成功
if(exceNew == null) {
//新增exce_new 表状态
exceNew = new ScheduleExceInfo();
exceNew.setCompileId(compileId);
exceNew.setIssueStatus(isValid);
exceNew.setExceTime(new Date());
exceNew.setIssueResult(issueResult);
exceNew.setErrorInfo(errorInfo);
exceNew.setIsIssue(0);
exceNew.setScheduleId(cfg.getId());
dao.insertScheduleExceNew(exceNew);
}else {
//修改 exce_new 表状态
exceNew.setExceTime(new Date());
exceNew.setIssueResult(issueResult);
exceNew.setErrorInfo(errorInfo);
exceNew.setScheduleId(cfg.getId());
dao.updateScheduleExceNew(exceNew);
}
ServiceConfigTemplateUtil serviceTemplate = new ServiceConfigTemplateUtil();
List<Map<String,Object>> serviceList = serviceTemplate.getServiceListByServiceId(cfg.getServiceId());
//根据编译ID查询配置表中的配置信息
for(Map<String,Object> service:serviceList){
//获取业务下的配置域
List<Map<String,Object>> cfgList = (List<Map<String, Object>>) service.get("cfgList");
//查询子域配置详情
if(cfgList!=null){
for(Map<String,Object> m:cfgList){
String regionTable = m.get("tableName").toString();
//更新配置域表的isValid字段
dao.updateCfgTableStatus(regionTable, compileId, isValid);
}
}
}
//3、更新 配置表的 isValid 字段,添加 exce_log 记录
dao.insertScheduleExceLog(exceNew);
dao.updateCfgTableStatus(tableName, compileId, isValid);
}
}
}

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"
default-lazy-init="true">
<!-- 配置加载 任务执行类 -->
<bean id="scheduleCfgJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.nis.quartz.ScheduleCfgJob"/>
<property name="name" value="scheduleCfgJobDetail" />
<property name="group" value="cfg" />
</bean>
<!-- 定时检查 schedule_cfg 表 -->
<bean id="scheduleCfgSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail">
<ref bean="scheduleCfgJobDetail" />
</property>
<property name="repeatInterval" value="10000" /><!-- 间隔 10s 执行一次 -->
<property name="startDelay" value="10000" /><!-- 延迟 10s 启动 -->
<property name="name" value="scheduleCfgTri" />
<property name="group" value="cfg" />
</bean>
<!-- 定时任务 -->
<bean id="NTCScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="dataSource" ref="ProductDataSource" /><!-- 配置数据源 -->
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<property name="configLocation" value="classpath:quartz.properties"/><!-- 加载配置文件 -->
<property name="autoStartup" value="true" /><!-- 自启动 -->
<property name="startupDelay" value="60" /><!-- 启动延迟时间 ,单位s-->
<property name="triggers">
<list>
<ref bean="scheduleCfgSimpleTrigger" />
</list>
</property>
</bean>
</beans>

View File

@@ -1482,14 +1482,16 @@ intercep_domain_required_tip=Domain is required
packets=packets
GByte=GByte
#\u5B9A\u65F6\u5668\u53C2\u6570
interval=Interval
month=Month
day=Day
interval=Recure every
month=Months
day=Days
week=weeks
startTime=Start Time
endTime=End Time
single=Single
everyDay=Every Day
everyWeek=Every Week
everyMonth=Every Month
single=One Time
everyDay=Daily
everyWeek=Weekly
everyMonth=Monthly
on=On
validate_error=Unexpected error occurred while validating
Is_schduler=Scheduler

View File

@@ -1,70 +1,74 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2009-2012 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true这个设置将强制使用被生成的主键有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE不隐射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<!--通过指定包名设置在相关映射时可使用不带包的简短名字bean的首字母小写作为默认别名 -->
<typeAliases>
<package name="com.nis.domain"/>
</typeAliases>
<!-- 插件配置 -->
<plugins>
<plugin interceptor="com.nis.persistence.interceptor.PaginationInterceptor" />
</plugins>
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2009-2012 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true这个设置将强制使用被生成的主键有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE不隐射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<!--通过指定包名设置在相关映射时可使用不带包的简短名字bean的首字母小写作为默认别名 -->
<typeAliases>
<package name="com.nis.domain"/>
</typeAliases>
<!-- 插件配置 -->
<plugins>
<plugin interceptor="com.nis.persistence.interceptor.PaginationInterceptor" />
<!-- 定时任务 更新保存 拦截器 -->
<plugin interceptor="com.nis.persistence.interceptor.ScheduleUpdateInterceptor" />
<!-- 定时任务 查询 -->
<plugin interceptor="com.nis.persistence.interceptor.ScheduleSelectInterceptor" />
</plugins>
</configuration>

View File

@@ -0,0 +1,17 @@
#################### quartz 相关配置文件 #########################
#Main Scheduler Settings
org.quartz.scheduler.instanceName=NTCScheduler
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true
org.quartz.scheduler.skipUpdateCheck=true
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=100
org.quartz.threadPool.threadCount=10
#Configure JDBC-JobStoreTX
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.acquireTriggersWithinLock=true
org.quartz.jobStore.clusterCheckinInterval = 30000

View File

@@ -11,13 +11,13 @@
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
</service>
<service id="37" functionId="5" serviceType="1" tableName="cfg_index_info" className="CfgIndexInfo" desc="ASN封堵">
<serviceCfg cfgType="1" tableName="asn_ip_cfg" groupReuse="true" groupId="userRegion4"></serviceCfg>
<userRegion regionKey="ASN_ID" regionColumn="userRegion5" userRegionPosition="0"></userRegion>
<serviceCfg cfgType="2" tableName="asn_keyword_cfg" groupReuse="true" groupId="userRegion4"></serviceCfg>
<!-- <userRegion regionKey="ASN_ID" regionColumn="userRegion5" userRegionPosition="0"></userRegion> -->
</service>
<service id="149" functionId="5" serviceType="1" tableName="cfg_index_info" className="CfgIndexInfo" desc="ASN监测">
<serviceCfg cfgType="2" tableName="asn_keyword_cfg" groupReuse="true" groupId="userRegion4"></serviceCfg>
<!-- <userRegion regionKey="ASN_ID" regionColumn="userRegion5" userRegionPosition="0" ></userRegion> -->
</service>
<!-- <service id="149" functionId="5" serviceType="1" tableName="cfg_index_info" className="CfgIndexInfo" desc="ASN监测">
<serviceCfg cfgType="1" tableName="asn_ip_cfg" groupReuse="true" groupId="userRegion4"></serviceCfg>
<userRegion regionKey="ASN_ID" regionColumn="userRegion5" userRegionPosition="0" ></userRegion>
</service> -->
<service id="3" functionId="5" serviceType="2" tableName="cfg_index_info" className="CfgIndexInfo" desc="IP丢弃">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
</service>
@@ -32,13 +32,13 @@
<userRegion regionKey="substitute" regionColumn="userRegion2,userRegion3" userRegionPosition="0"></userRegion>
</service>
<!-- IP Spoofing的地址IP池 回调类配置 -->
<service id="642" functionId="666" serviceType="2" tableName="pxy_obj_spoofing_ip_pool" className="PxyObjSpoofingIpPool" desc="IP Spoofing Pool"></service>
<!-- <service id="642" functionId="666" serviceType="2" tableName="pxy_obj_spoofing_ip_pool" className="PxyObjSpoofingIpPool" desc="IP Spoofing Pool"></service> -->
<service id="518" functionId="214" serviceType="1" tableName="cfg_index_info" className="CfgIndexInfo" desc="IP Spoofing">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
<serviceCfg cfgType="2" tableName="intercept_pkt_bin" ></serviceCfg>
<userRegion regionKey="zone" regionColumn="userRegion1" userRegionPosition="0"></userRegion>
<userRegion regionKey="substitute" regionColumn="userRegion2,userRegion3" userRegionPosition="0"></userRegion>
<!-- <serviceCfg cfgType="2" tableName="intercept_pkt_bin" ></serviceCfg> --> -->
<userRegion regionKey="nat_type" regionColumn="userRegion1" userRegionPosition="0"></userRegion>
<userRegion regionKey="spoofing_ip_pool" regionColumn="userRegion3" userRegionPosition="0"></userRegion>
</service>
<service id="2" functionId="6" serviceType="1" tableName="cfg_index_info" className="CfgIndexInfo" desc="URL白名单">
<serviceCfg cfgType="2" tableName="http_url_cfg" ></serviceCfg>
@@ -279,21 +279,22 @@
<serviceCfg cfgType="2" tableName="ntc_subscribe_id_cfg" ></serviceCfg>
<userRegion regionKey="PROTO_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="Droprate" regionColumn="userRegion2" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="33" functionId="63" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="APP封堵">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
<serviceCfg cfgType="2" tableName="ntc_subscribe_id_cfg" ></serviceCfg>
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
<userRegion regionKey="DKC" regionColumn="userRegion4" userRegionPosition="1"></userRegion>
</service>
<service id="145" functionId="63" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="APP监测">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
<serviceCfg cfgType="2" tableName="ntc_subscribe_id_cfg" ></serviceCfg>
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="1056" functionId="63" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="APP限速">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
@@ -301,21 +302,21 @@
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="Droprate" regionColumn="userRegion2" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="36" functionId="408" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="隧道协议行为封堵">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
<serviceCfg cfgType="2" tableName="ntc_subscribe_id_cfg" ></serviceCfg>
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="148" functionId="408" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="隧道协议行为监测">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
<serviceCfg cfgType="2" tableName="ntc_subscribe_id_cfg" ></serviceCfg>
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="1060" functionId="408" serviceType="1" tableName="app_policy_cfg" className="AppPolicyCfg" desc="隧道协议行为限速">
<serviceCfg cfgType="1" tableName="ip_port_cfg" ></serviceCfg>
@@ -323,7 +324,7 @@
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="BEHAV_ID" regionColumn="behavCode" userRegionPosition="1"></userRegion>
<userRegion regionKey="Droprate" regionColumn="userRegion2" userRegionPosition="1"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="0"></userRegion>
<userRegion regionKey="config_id" regionColumn="compileId" userRegionPosition="1"></userRegion>
</service>
<service id="1028" functionId="405" serviceType="1" cfgType="1" tableName="app_ip_cfg" className="AppIpCfg" desc="APP IP特征">
<userRegion regionKey="APP_ID" regionColumn="appCode" userRegionPosition="1"></userRegion>

View File

@@ -0,0 +1,2 @@
[users]
admin=admin!@#,Superman

View File

@@ -0,0 +1,179 @@
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
# I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
commit;

View File

@@ -0,0 +1,81 @@
/*
Navicat Premium Data Transfer
Source Server : 本机
Source Server Type : MariaDB
Source Server Version : 100214
Source Host : 127.0.0.1:3306
Source Schema : ntc
Target Server Type : MariaDB
Target Server Version : 100214
File Encoding : 65001
Date: 02/01/2019 17:15:01
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for schedule_cfg
-- ----------------------------
DROP TABLE IF EXISTS `schedule_cfg`;
CREATE TABLE `schedule_cfg` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务名称,预留',
`cron_valid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时:月份',
`cron_invalid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时:天',
`cfg_id` bigint(20) NOT NULL COMMENT '配置表id',
`compile_id` bigint(20) NOT NULL COMMENT '编译id',
`service_id` int(11) NOT NULL COMMENT '业务id',
`is_valid` int(11) NOT NULL DEFAULT 1 COMMENT '配置生效标识1:有效,0:无效',
`is_audit` int(1) NULL DEFAULT NULL COMMENT '审核状态',
`function_id` int(11) NULL DEFAULT NULL COMMENT 'function id',
`creator_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`editor_id` int(11) NULL DEFAULT NULL COMMENT '修改人id',
`edit_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`table_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表名',
`user_region1` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`user_region2` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`user_region3` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`user_region4` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`user_region5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`del_flag` int(1) NULL DEFAULT 1 COMMENT '删除标识,定时任务是否有效默认1',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for schedule_exce_log
-- ----------------------------
DROP TABLE IF EXISTS `schedule_exce_log`;
CREATE TABLE `schedule_exce_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`schedule_id` bigint(20) NOT NULL COMMENT 'schedule_info 表的主键',
`exce_time` datetime(0) NULL DEFAULT NULL COMMENT '最新执行时间',
`issue_status` int(255) NULL DEFAULT NULL COMMENT '下发状态1生效0失效',
`issue_result` int(255) NULL DEFAULT NULL COMMENT '下发结果1成功0失败',
`error_info` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '下发失败原因',
`compile_id` bigint(20) NULL DEFAULT NULL COMMENT '编译id',
`is_issue` int(1) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for schedule_exce_new
-- ----------------------------
DROP TABLE IF EXISTS `schedule_exce_new`;
CREATE TABLE `schedule_exce_new` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`schedule_id` bigint(20) NOT NULL COMMENT 'schedule_info 表的主键',
`exce_time` datetime(0) NULL DEFAULT NULL COMMENT '最新执行时间',
`issue_status` int(255) NULL DEFAULT NULL COMMENT '下发状态1生效0失效',
`issue_result` int(255) NULL DEFAULT NULL COMMENT '下发结果1成功0失败',
`error_info` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '下发失败原因',
`compile_id` bigint(20) NULL DEFAULT NULL COMMENT '编译id',
`is_issue` int(255) NULL DEFAULT 0 COMMENT '是否需要下发配置10',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,111 @@
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/include/taglib.jsp"%>
<script type="text/javascript">
$(function(){
//字段添加索引
function refreshIndex(){
$("div.row.cron").each(function(i,n){
var $this = $(this);
$this.find("input").each(function(){
var $input = $(this);
var name = $input.attr("name");
console.log(name);
$input.attr("name",name.replace(/\[\d*\]/,"["+i+"]"));
});
});
}
//cron 动态添加
$("span.CronAdd").on("click",function(){
var hourCnt = $("div.cron");
if (hourCnt.length < 5) {//输入框限制为4个包含 template 为 5个
var $tpl = $(".cron.template");
var clone = $tpl.clone().removeClass("template").removeClass("hidden").removeClass("disabled");
$tpl.before(clone);
clone.find(".cronDiv").each(function(ii,nn){
$(this).cron({
initial: "0 0 1 * *",//每月1号执行
onChange: function() {
$(this).siblings("input[type='hidden']").val($(this).cron("value"));
},
});
});
refreshIndex();
}
});
//动态删除
$(document).on("click","span.CronRemove",function(event){
$(this).closest("div.cron").remove();
refreshIndex();
});
});
</script>
<style>
.row.cron {
border: 1px solid #eee;
margin: 0px 0px 5px 0px;
padding: 0px;
}
div.cronDiv {
padding-top: 7px;
}
</style>
<!-- 周期任务 -->
<h4 class="form-section">
<spring:message code="Schedule"/>
<small>
<!-- 定时任务 添加按钮 -->
<span class="glyphicon glyphicon-plus CronAdd" title="add Schedule"></span>
</small>
</h4>
<!-- 复现cron配置 start -->
<c:forEach items="${_cfg.schedules }" var="cron" varStatus="vs">
<div class="row cron">
<div class="row">
<div class="pull-right">
<input type="hidden" name="schedules[${vs.index}].id" value="${cron.id }"/>
<span class="glyphicon glyphicon-remove pull-right CronRemove" title="remove Schedule"/>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-2"><spring:message code="Valid" /></label>
<div class="col-md-9 cronDiv" ></div>
<input type="hidden" name="schedules[${vs.index}].cronValid" value="${cron.cronValid }">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-2"><spring:message code="Invalid" /></label>
<div class="col-md-9 cronDiv" ></div>
<input type="hidden" name="schedules[${vs.index}].cronInvalid" value="${cron.cronInvalid }">
</div>
</div>
</div>
</c:forEach>
<!-- 复现cron配置 end -->
<div class="row cron template hidden disabled">
<div class="row">
<div class="pull-right">
<span class="glyphicon glyphicon-remove pull-right CronRemove" title="remove Schedule"/>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-2"><spring:message code="Valid" /></label>
<div class="col-md-9 cronDiv" ></div>
<input type="hidden" name="schedules[].cronValid" value="">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-2"><spring:message code="Invalid" /></label>
<div class="col-md-9 cronDiv" ></div>
<input type="hidden" name="schedules[].cronInvalid" value="">
</div>
</div>
</div>

View File

@@ -0,0 +1,307 @@
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/include/taglib.jsp"%>
<style>
#cron{
margin-bottom: 10px;
}
.detail{
border-left: 2px solid #999;
}
</style>
<script>
$(function(){
//day week 切换
function initDayWeek(){
var dayWeekCheck = $("input.dayWeek:checked");
$("div.dayWeek select").attr("disabled","disabled");
var selects = dayWeekCheck.parents(".dayWeek").find("select");
selects.attr("disabled",false)
$("div.dayWeek select").selectpicker('refresh');
}
function modeChange(){
var modeCheck = $("#cron input.every:checked");
var val = modeCheck.val();
//隐藏 cronRight 所有元素
$(".detail > div").addClass("hidden");
$(".detail > div").addClass("disabled");
$(".detail ." +val ).removeClass("hidden");
$(".detail ." +val ).removeClass("disabled");
}
function init(){
//初始化 mode 模式,一次,每天,每周,每月
modeChange();
//初始化 每月 day week切换
initDayWeek();
var modeCheck = $("#cron input.every:checked");
var val = modeCheck.val();
//复现内容,清除 其它 选项下的值
$(".detail > div").not("."+val).find("input[type!='radio']").val("");
$(".detail > div").not("."+val).find("select").val("");
//初始化 number 的默认值
$("input[type='number']").each(function(){
var val = $(this).val();
if(!val || '' == val ){
$(this).val(1);
}
});
}
$("#cron input.every").on("click",function(){
var $this = $(this);
modeChange();
});
//每月 日 和 周切换按钮
$("input.dayWeek").on("click",function(){
var $this = $(this);
initDayWeek();
});
init();
//删除
$(document).on("click","span.CronRemove",function(event){
$("#cron").addClass("hidden").addClass("disabled");
$(".CronAdd").removeClass("hidden");
});
//cron 动态添加
$("span.CronAdd").on("click",function(){
$("#cron").removeClass("hidden").removeClass("disabled");
$(".CronAdd").addClass("hidden");
});
});
</script>
<!-- 周期任务 -->
<h4 class="form-section">
<spring:message code="Schedule"/>
<small>
<!-- 定时任务 添加按钮 -->
<span class='glyphicon glyphicon-plus CronAdd <c:if test="${not empty _cfg.schedule }">hidden</c:if>' title="add Schedule" ></span>
</small>
</h4>
<div id="cron" class='row <c:if test="${empty _cfg.schedule }">hidden disabled</c:if>' >
<div class="row">
<div class="pull-right">
<span class="glyphicon glyphicon-remove pull-right CronRemove" title="remove Schedule"/>
</div>
</div>
<div class="col-md-2 zhanwei"></div>
<div class="col-md-1 mode"><!-- 一次,每天,每周,每月选择 -->
<div class="form-group">
<label class="radio-inline">
<input id="single" type="radio" class="required every" name="schedule.userRegion1" value="single" checked="checked" <c:if test="${_cfg.schedule.userRegion1 == 'single' }">checked="checked"</c:if>><spring:message code="single"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyDay" type="radio" class="required every" name="schedule.userRegion1" value="everyDay" <c:if test="${_cfg.schedule.userRegion1 == 'everyDay' }">checked="checked"</c:if>><spring:message code="everyDay"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyWeek" type="radio" class="required every" name="schedule.userRegion1" value="everyWeek" <c:if test="${_cfg.schedule.userRegion1 == 'everyWeek' }">checked="checked"</c:if>><spring:message code="everyWeek"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyMonth" type="radio" class="required every" name="schedule.userRegion1" value="everyMonth" <c:if test="${_cfg.schedule.userRegion1 == 'everyMonth' }">checked="checked"</c:if>><spring:message code="everyMonth"/>
</label>
</div>
</div>
<div class="col-md-9 detail">
<!-- 一次执行 -->
<div class="single">
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="startTime"/></label>
<div class="col-md-4">
<input name="schedule.cronValid" id="singleValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:true,minDate:'%y-%M-%d %H:{%m+2}:%s', maxDate:'#F{$dp.$D(\'singleInvalid\')}'});"/>
</div>
<div for="schedule.cronValid"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" id="singleInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:true,minDate:'#F{$dp.$D(\'singleValid\')}'});"/>
</div>
<div for="schedule.cronInvalid"></div>
</div>
</div>
<!-- 每天执行 -->
<div class="everyDay hidden">
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="interval"/></label>
<div class="col-md-2">
<!-- 间隔 interval -->
<input name="schedule.userRegion2" type="number" class="form-control required" value="${_cfg.schedule.userRegion2 }" min="1" />
<%-- <spring:message code="day"/> --%>
</div>
<div for="schedule.userRegion2"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronValid"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronInvalid"></div>
</div>
</div>
<!-- 每周执行 -->
<div class="everyWeek hidden">
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="interval"/></label>
<div class="col-md-2">
<input name="schedule.userRegion2" type="number" class="form-control required" value="${_cfg.schedule.userRegion2 }" min="1" />
<%-- <spring:message code="week"/> --%>
</div>
<div for="schedule.userRegion2"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="on"/></label>
<div class="col-md-4">
<select name="schedule.userRegion3" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"1")}'>selected="selected"</c:if>><spring:message code="Monday"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"2")}'>selected="selected"</c:if>><spring:message code="Tuesday"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"3")}'>selected="selected"</c:if>><spring:message code="Wednesday"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"4")}'>selected="selected"</c:if>><spring:message code="Thursday"/></option>
<option value="5" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"5")}'>selected="selected"</c:if>><spring:message code="Friday"/></option>
<option value="6" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"6")}'>selected="selected"</c:if>><spring:message code="Saturday"/></option>
<option value="7" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"7")}'>selected="selected"</c:if>><spring:message code="Sunday"/></option>
</select>
</div>
<div for="schedule.userRegion3"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronValid"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronInvalid"></div>
</div>
</div>
<!-- 每月执行 -->
<div class="everyMonth hidden">
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="month"/></label>
<div class="col-md-6">
<select name="schedule.userRegion2" multiple data-actions-box="true" class="selectpicker form-control required">
<c:set var="months" value=",${_cfg.schedule.userRegion2},"></c:set>
<option value="1" <c:if test='${fn:contains(months , ",1,")}'>selected="selected"</c:if>><spring:message code="January"/></option>
<option value="2" <c:if test='${fn:contains(months , ",2,")}'>selected="selected"</c:if>><spring:message code="February"/></option>
<option value="3" <c:if test='${fn:contains(months , ",3,")}'>selected="selected"</c:if>><spring:message code="March"/></option>
<option value="4" <c:if test='${fn:contains(months , ",4,")}'>selected="selected"</c:if>><spring:message code="April"/></option>
<option value="5" <c:if test='${fn:contains(months , ",5,")}'>selected="selected"</c:if>><spring:message code="May"/></option>
<option value="6" <c:if test='${fn:contains(months , ",6,")}'>selected="selected"</c:if>><spring:message code="June"/></option>
<option value="7" <c:if test='${fn:contains(months , ",7,")}'>selected="selected"</c:if>><spring:message code="July"/></option>
<option value="8" <c:if test='${fn:contains(months , ",8,")}'>selected="selected"</c:if>><spring:message code="August"/></option>
<option value="9" <c:if test='${fn:contains(months , ",9,")}'>selected="selected"</c:if>><spring:message code="September"/></option>
<option value="10" <c:if test='${fn:contains(months , ",10,")}'>selected="selected"</c:if>><spring:message code="October"/></option>
<option value="11" <c:if test='${fn:contains(months , ",11,")}'>selected="selected"</c:if>><spring:message code="November"/></option>
<option value="12" <c:if test='${fn:contains(months , ",12,")}'>selected="selected"</c:if>><spring:message code="December"/></option>
</select>
</div>
<div for="schedule.userRegion2"></div>
</div>
<!-- 天 -->
<div class="form-group dayWeek">
<label class="control-label col-md-2"><input type="radio" name="schedule.userRegion3" value="day" class="dayWeek required" checked="checked" <c:if test='${_cfg.schedule.userRegion3 == "day" }'>checked="checked"</c:if>/> <spring:message code="day"/></label>
<div class="col-md-6">
<select name="schedule.userRegion4" multiple data-actions-box="true" class="selectpicker form-control required">
<c:set var="days" value=",${_cfg.schedule.userRegion4},"></c:set>
<option value="1" <c:if test='${fn:contains(days , ",1,")}'>selected="selected"</c:if>>1</option>
<option value="2" <c:if test='${fn:contains(days , ",2,")}'>selected="selected"</c:if>>2</option>
<option value="3" <c:if test='${fn:contains(days , ",3,")}'>selected="selected"</c:if>>3</option>
<option value="4" <c:if test='${fn:contains(days , ",4,")}'>selected="selected"</c:if>>4</option>
<option value="5" <c:if test='${fn:contains(days , ",5,")}'>selected="selected"</c:if>>5</option>
<option value="6" <c:if test='${fn:contains(days , ",6,")}'>selected="selected"</c:if>>6</option>
<option value="7" <c:if test='${fn:contains(days , ",7,")}'>selected="selected"</c:if>>7</option>
<option value="8" <c:if test='${fn:contains(days , ",8,")}'>selected="selected"</c:if>>8</option>
<option value="9" <c:if test='${fn:contains(days , ",9,")}'>selected="selected"</c:if>>9</option>
<option value="10" <c:if test='${fn:contains(days , ",10,")}'>selected="selected"</c:if>>10</option>
<option value="11" <c:if test='${fn:contains(days , ",11,")}'>selected="selected"</c:if>>11</option>
<option value="12" <c:if test='${fn:contains(days , ",12,")}'>selected="selected"</c:if>>12</option>
<option value="13" <c:if test='${fn:contains(days , ",13,")}'>selected="selected"</c:if>>13</option>
<option value="14" <c:if test='${fn:contains(days , ",14,")}'>selected="selected"</c:if>>14</option>
<option value="15" <c:if test='${fn:contains(days , ",15,")}'>selected="selected"</c:if>>15</option>
<option value="16" <c:if test='${fn:contains(days , ",16,")}'>selected="selected"</c:if>>16</option>
<option value="17" <c:if test='${fn:contains(days , ",17,")}'>selected="selected"</c:if>>17</option>
<option value="18" <c:if test='${fn:contains(days , ",18,")}'>selected="selected"</c:if>>18</option>
<option value="19" <c:if test='${fn:contains(days , ",19,")}'>selected="selected"</c:if>>19</option>
<option value="20" <c:if test='${fn:contains(days , ",20,")}'>selected="selected"</c:if>>20</option>
<option value="21" <c:if test='${fn:contains(days , ",21,")}'>selected="selected"</c:if>>21</option>
<option value="22" <c:if test='${fn:contains(days , ",22,")}'>selected="selected"</c:if>>22</option>
<option value="23" <c:if test='${fn:contains(days , ",23,")}'>selected="selected"</c:if> >23</option>
<option value="24" <c:if test='${fn:contains(days , ",24,")}'>selected="selected"</c:if>>24</option>
<option value="25" <c:if test='${fn:contains(days , ",25,")}'>selected="selected"</c:if>>25</option>
<option value="26" <c:if test='${fn:contains(days , ",26,")}'>selected="selected"</c:if>>26</option>
<option value="27" <c:if test='${fn:contains(days , ",27,")}'>selected="selected"</c:if>>27</option>
<option value="28" <c:if test='${fn:contains(days , ",28,")}'>selected="selected"</c:if>>28</option>
<option value="29" <c:if test='${fn:contains(days , ",29,")}'>selected="selected"</c:if>>29</option>
<option value="30" <c:if test='${fn:contains(days , ",30,")}'>selected="selected"</c:if>>30</option>
<option value="31" <c:if test='${fn:contains(days , ",31,")}'>selected="selected"</c:if>>31</option>
<option value="L" <c:if test='${fn:contains(days , ",L,")}'>selected="selected"</c:if>><spring:message code="lastDay"/></option>
</select>
</div>
<div for="schedule.userRegion4"></div>
</div>
<div class="form-group dayWeek">
<label class="control-label col-md-2"><input type="radio" name="schedule.userRegion3" class="dayWeek required" value="week" <c:if test='${_cfg.schedule.userRegion3 == "week" }'>checked="checked"</c:if>/> <spring:message code="on"/></label>
<div class="col-md-3">
<select name="schedule.userRegion4" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"1")}'>selected="selected"</c:if>><spring:message code="firstWeek"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"2")}'>selected="selected"</c:if>><spring:message code="secondWeek"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"3")}'>selected="selected"</c:if>><spring:message code="thirdWeek"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"4")}'>selected="selected"</c:if>><spring:message code="fourthWeek"/></option>
<option value="L" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"L")}'>selected="selected"</c:if>><spring:message code="lastWeek"/></option>
</select>
</div>
<div class="col-md-3">
<select name="schedule.userRegion5" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"1")}'>selected="selected"</c:if>><spring:message code="Monday"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"2")}'>selected="selected"</c:if>><spring:message code="Tuesday"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"3")}'>selected="selected"</c:if>><spring:message code="Wednesday"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"4")}'>selected="selected"</c:if>><spring:message code="Thursday"/></option>
<option value="5" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"5")}'>selected="selected"</c:if>><spring:message code="Friday"/></option>
<option value="6" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"6")}'>selected="selected"</c:if>><spring:message code="Saturday"/></option>
<option value="7" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"7")}'>selected="selected"</c:if>><spring:message code="Sunday"/></option>
</select>
</div>
<div for="schedule.userRegion4"></div>
<div for="schedule.userRegion5"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value='${_cfg.schedule.cronValid }' onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronValid"></div>
</div>
<div class="form-group ">
<label class="control-label col-md-2"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value='${_cfg.schedule.cronInvalid }' onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
<div for="schedule.cronInvalid"></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,250 @@
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/include/taglib.jsp"%>
<style>
#cron{
margin-bottom: 10px;
}
.detail{
border-left: 2px solid #999;
}
.detail .control-label{
text-align: right;
padding-right: 10px;
}
</style>
<script>
$(function(){
function init(){
//初始化 mode 模式,一次,每天,每周,每月
$("div.cronContain ").each(function(i,n){
var $this = $(this);
var mode = $this.find("input.every:checked").val();
//隐藏 cronRight 所有元素
$this .find(".detail > div").addClass("hidden");
$this.find(".detail > div").addClass("disabled");
$this.find(".detail ." +mode ).removeClass("hidden");
//复现内容,清除 其它 选项下的值
$this.find(".detail > div").not("."+mode).find("input").val("");
$this.find(".detail > div").not("."+mode).find("select").val("");
$this.find("input").attr("disabled","disabled").attr("name",function(){
return $(this).attr("name") + i;
});
$this.find("select").attr("disabled","disabled").attr("name",function(){
return $(this).attr("name") + i;
});
$this.find("input[type='radio']:not(:checked)").closest(".form-group").remove();
$this.find("select:visible").selectpicker('refresh');
});
}
init();
});
</script>
<div id="cron" class=' cronContain row <c:if test="${empty _cfg.schedule }">hidden</c:if>' >
<div class="col-md-1 mode"><!-- 一次,每天,每周,每月选择 -->
<div class="form-group">
<label class="radio-inline">
<input id="single" type="radio" class="required every" name="schedule.userRegion1" value="single" checked="checked" <c:if test="${_cfg.schedule.userRegion1 == 'single' }">checked="checked"</c:if>><spring:message code="single"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyDay" type="radio" class="required every" name="schedule.userRegion1" value="everyDay" <c:if test="${_cfg.schedule.userRegion1 == 'everyDay' }">checked="checked"</c:if>><spring:message code="everyDay"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyWeek" type="radio" class="required every" name="schedule.userRegion1" value="everyWeek" <c:if test="${_cfg.schedule.userRegion1 == 'everyWeek' }">checked="checked"</c:if>><spring:message code="everyWeek"/>
</label>
</div>
<div class="form-group">
<label class="radio-inline">
<input id="everyMonth" type="radio" class="required every" name="schedule.userRegion1" value="everyMonth" <c:if test="${_cfg.schedule.userRegion1 == 'everyMonth' }">checked="checked"</c:if>><spring:message code="everyMonth"/>
</label>
</div>
</div>
<div class="col-md-9 detail">
<!-- 一次执行 -->
<div class="single">
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="startTime"/></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:true});"/>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:true});"/>
</div>
</div>
</div>
<!-- 每天执行 -->
<div class="everyDay hidden">
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="interval"/></label>
<div class="col-md-1">
<!-- 间隔 interval -->
<input name="schedule.userRegion2" type="number" class="form-control required" value="${_cfg.schedule.userRegion2 }" min="1" />
<%-- <spring:message code="day"/> --%>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
</div>
<!-- 每周执行 -->
<div class="everyWeek hidden">
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="interval"/></label>
<div class="col-md-1">
<input name="schedule.userRegion2" type="number" class="form-control required" value="${_cfg.schedule.userRegion2 }" min="1" />
<%-- <spring:message code="week"/> --%>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="on"/></label>
<div class="col-md-4">
<select name="schedule.userRegion3" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"1")}'>selected="selected"</c:if>><spring:message code="Monday"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"2")}'>selected="selected"</c:if>><spring:message code="Tuesday"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"3")}'>selected="selected"</c:if>><spring:message code="Wednesday"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"4")}'>selected="selected"</c:if>><spring:message code="Thursday"/></option>
<option value="5" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"5")}'>selected="selected"</c:if>><spring:message code="Friday"/></option>
<option value="6" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"6")}'>selected="selected"</c:if>><spring:message code="Saturday"/></option>
<option value="7" <c:if test='${fn:contains(_cfg.schedule.userRegion3,"7")}'>selected="selected"</c:if>><spring:message code="Sunday"/></option>
</select>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronValid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value="${_cfg.schedule.cronInvalid }" onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
</div>
<div class="everyMonth hidden">
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="month"/></label>
<div class="col-md-6">
<select name="schedule.userRegion2" multiple data-actions-box="true" class="selectpicker form-control required">
<c:set var="months" value=",${_cfg.schedule.userRegion2},"></c:set>
<option value="1" <c:if test='${fn:contains(months , ",1,")}'>selected="selected"</c:if>><spring:message code="January"/></option>
<option value="2" <c:if test='${fn:contains(months , ",2,")}'>selected="selected"</c:if>><spring:message code="February"/></option>
<option value="3" <c:if test='${fn:contains(months , ",3,")}'>selected="selected"</c:if>><spring:message code="March"/></option>
<option value="4" <c:if test='${fn:contains(months , ",4,")}'>selected="selected"</c:if>><spring:message code="April"/></option>
<option value="5" <c:if test='${fn:contains(months , ",5,")}'>selected="selected"</c:if>><spring:message code="May"/></option>
<option value="6" <c:if test='${fn:contains(months , ",6,")}'>selected="selected"</c:if>><spring:message code="June"/></option>
<option value="7" <c:if test='${fn:contains(months , ",7,")}'>selected="selected"</c:if>><spring:message code="July"/></option>
<option value="8" <c:if test='${fn:contains(months , ",8,")}'>selected="selected"</c:if>><spring:message code="August"/></option>
<option value="9" <c:if test='${fn:contains(months , ",9,")}'>selected="selected"</c:if>><spring:message code="September"/></option>
<option value="10" <c:if test='${fn:contains(months , ",10,")}'>selected="selected"</c:if>><spring:message code="October"/></option>
<option value="11" <c:if test='${fn:contains(months , ",11,")}'>selected="selected"</c:if>><spring:message code="November"/></option>
<option value="12" <c:if test='${fn:contains(months , ",12,")}'>selected="selected"</c:if>><spring:message code="December"/></option>
</select>
</div>
</div>
<!-- 天 -->
<div class="form-group dayWeek row">
<label class="control-label col-md-1"><input type="radio" name="schedule.userRegion3" value="day" class="dayWeek required" checked="checked" <c:if test='${_cfg.schedule.userRegion3 == "day" }'>checked="checked"</c:if>/> <spring:message code="day"/></label>
<div class="col-md-6">
<select name="schedule.userRegion4" multiple data-actions-box="true" class="selectpicker form-control required">
<c:set var="days" value=",${_cfg.schedule.userRegion4},"></c:set>
<option value="1" <c:if test='${fn:contains(days , ",1,")}'>selected="selected"</c:if>>1</option>
<option value="2" <c:if test='${fn:contains(days , ",2,")}'>selected="selected"</c:if>>2</option>
<option value="3" <c:if test='${fn:contains(days , ",3,")}'>selected="selected"</c:if>>3</option>
<option value="4" <c:if test='${fn:contains(days , ",4,")}'>selected="selected"</c:if>>4</option>
<option value="5" <c:if test='${fn:contains(days , ",5,")}'>selected="selected"</c:if>>5</option>
<option value="6" <c:if test='${fn:contains(days , ",6,")}'>selected="selected"</c:if>>6</option>
<option value="7" <c:if test='${fn:contains(days , ",7,")}'>selected="selected"</c:if>>7</option>
<option value="8" <c:if test='${fn:contains(days , ",8,")}'>selected="selected"</c:if>>8</option>
<option value="9" <c:if test='${fn:contains(days , ",9,")}'>selected="selected"</c:if>>9</option>
<option value="10" <c:if test='${fn:contains(days , ",10,")}'>selected="selected"</c:if>>10</option>
<option value="11" <c:if test='${fn:contains(days , ",11,")}'>selected="selected"</c:if>>11</option>
<option value="12" <c:if test='${fn:contains(days , ",12,")}'>selected="selected"</c:if>>12</option>
<option value="13" <c:if test='${fn:contains(days , ",13,")}'>selected="selected"</c:if>>13</option>
<option value="14" <c:if test='${fn:contains(days , ",14,")}'>selected="selected"</c:if>>14</option>
<option value="15" <c:if test='${fn:contains(days , ",15,")}'>selected="selected"</c:if>>15</option>
<option value="16" <c:if test='${fn:contains(days , ",16,")}'>selected="selected"</c:if>>16</option>
<option value="17" <c:if test='${fn:contains(days , ",17,")}'>selected="selected"</c:if>>17</option>
<option value="18" <c:if test='${fn:contains(days , ",18,")}'>selected="selected"</c:if>>18</option>
<option value="19" <c:if test='${fn:contains(days , ",19,")}'>selected="selected"</c:if>>19</option>
<option value="20" <c:if test='${fn:contains(days , ",20,")}'>selected="selected"</c:if>>20</option>
<option value="21" <c:if test='${fn:contains(days , ",21,")}'>selected="selected"</c:if>>21</option>
<option value="22" <c:if test='${fn:contains(days , ",22,")}'>selected="selected"</c:if>>22</option>
<option value="23" <c:if test='${fn:contains(days , ",23,")}'>selected="selected"</c:if> >23</option>
<option value="24" <c:if test='${fn:contains(days , ",24,")}'>selected="selected"</c:if>>24</option>
<option value="25" <c:if test='${fn:contains(days , ",25,")}'>selected="selected"</c:if>>25</option>
<option value="26" <c:if test='${fn:contains(days , ",26,")}'>selected="selected"</c:if>>26</option>
<option value="27" <c:if test='${fn:contains(days , ",27,")}'>selected="selected"</c:if>>27</option>
<option value="28" <c:if test='${fn:contains(days , ",28,")}'>selected="selected"</c:if>>28</option>
<option value="29" <c:if test='${fn:contains(days , ",29,")}'>selected="selected"</c:if>>29</option>
<option value="30" <c:if test='${fn:contains(days , ",30,")}'>selected="selected"</c:if>>30</option>
<option value="31" <c:if test='${fn:contains(days , ",31,")}'>selected="selected"</c:if>>31</option>
<option value="L" <c:if test='${fn:contains(days , ",L,")}'>selected="selected"</c:if>><spring:message code="lastDay"/></option>
</select>
</div>
</div>
<div class="form-group dayWeek row">
<label class="control-label col-md-1"><input type="radio" name="schedule.userRegion3" class="dayWeek required" value="week" <c:if test='${_cfg.schedule.userRegion3 == "week" }'>checked="checked"</c:if>/> <spring:message code="on"/></label>
<div class="col-md-3">
<select name="schedule.userRegion4" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"1")}'>selected="selected"</c:if>><spring:message code="firstWeek"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"2")}'>selected="selected"</c:if>><spring:message code="secondWeek"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"3")}'>selected="selected"</c:if>><spring:message code="thirdWeek"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"4")}'>selected="selected"</c:if>><spring:message code="fourthWeek"/></option>
<option value="L" <c:if test='${fn:contains(_cfg.schedule.userRegion4,"L")}'>selected="selected"</c:if>><spring:message code="lastWeek"/></option>
</select>
</div>
<div class="col-md-3">
<select name="schedule.userRegion5" multiple data-actions-box="true" class="selectpicker form-control required">
<option value="1" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"1")}'>selected="selected"</c:if>><spring:message code="Monday"/></option>
<option value="2" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"2")}'>selected="selected"</c:if>><spring:message code="Tuesday"/></option>
<option value="3" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"3")}'>selected="selected"</c:if>><spring:message code="Wednesday"/></option>
<option value="4" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"4")}'>selected="selected"</c:if>><spring:message code="Thursday"/></option>
<option value="5" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"5")}'>selected="selected"</c:if>><spring:message code="Friday"/></option>
<option value="6" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"6")}'>selected="selected"</c:if>><spring:message code="Saturday"/></option>
<option value="7" <c:if test='${fn:contains(_cfg.schedule.userRegion5,"7")}'>selected="selected"</c:if>><spring:message code="Sunday"/></option>
</select>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="startTime"></spring:message></label>
<div class="col-md-4">
<input name="schedule.cronValid" type="text" class="form-control Wdate required" readonly="readonly" value='${_cfg.schedule.cronValid }' onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-1"><spring:message code="endTime"/></label>
<div class="col-md-4">
<input name="schedule.cronInvalid" type="text" class="form-control Wdate required" readonly="readonly" value='${_cfg.schedule.cronInvalid }' onClick="WdatePicker({dateFmt:'H:mm:ss'})"/>
</div>
</div>
</div>
</div>
</div>

View File

@@ -109,6 +109,12 @@ function del(url){
function update(url){
var checkboxes=$("#${id} ${value} tbody tr td input.i-checks:checkbox");
var cked = $("tbody tr td input.i-checks:checkbox:checked");
var schedulerFlag = $(cked).parent().parent().find(".schedulerFlag").find("span").attr("isScheduler");
if(schedulerFlag!= "undefined" && schedulerFlag=="yes"){//验证配置是否是定时任务,如果是定时任务,不允许修改
top.$.jBox.tip("<spring:message code='scheduler_warning'/>", "<spring:message code='info'/>");
return;
}
if($(checkboxes).filter(":checked").length==1){
if(cked.val()==1){
//增加asn ip域配置判断如果是asn ip业务审核通过的也可以修改 functionId=600
@@ -140,6 +146,10 @@ function passOpt(url){
var checkboxes=$("#${id} ${value} tbody tr td input.i-checks:checkbox");
if($(checkboxes).filter(":checked").length>0){
if(validateIsScheduler(checkboxes)){//验证配置是否是定时任务,如果是定时任务,不允许手动审核
top.$.jBox.tip("<spring:message code='scheduler_warning'/>", "<spring:message code='info'/>");
return;
}
if(validateAllNoAudit(checkboxes)){
top.$.jBox.tip("<spring:message code='has_prohibit_pass'/>", "<spring:message code='info'/>");
return;
@@ -497,6 +507,17 @@ function cancelPassOpt(url){
});
return flag;
}
function validateIsScheduler(checkboxes){
var flag = false;
$(checkboxes).filter(":checked").each(function(){
var schedulerFlag = $(this).parent().parent().find(".schedulerFlag").find("span").attr("isScheduler");
if(schedulerFlag!= "undefined" && schedulerFlag=="yes"){
flag = true;
return;
}
});
return flag;
}
//导出
function exportData(url,maxRow,searchUrl,exType){
var column=[];

View File

@@ -0,0 +1,35 @@
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/include/taglib.jsp"%>
<html>
<head>
<title></title>
<script type="text/javascript">
</script>
</head>
<div class="row">
<div class="pull-right">
<span class="glyphicon glyphicon-remove pull-right" title="remove"
onClick="delContent('${tabName}${status.index}','${tabName}Add');" />
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<%-- <input type="hidden" name="userRegion5" value="${_cfg.userRegion5}"> --%>
<div class="form-group">
<label class="control-label col-md-3"><font color="red">*</font><spring:message code="ASN"/></label>
<div class="col-md-6">
<%-- <select name="userRegion4" class="selectpicker show-tick form-control required" data-live-search="true" data-live-search-placeholder="search">
<c:forEach items="${policyGroups }" var="policyGroup">
<option asnId="${policyGroup.asnId}" value="${policyGroup.groupName}" <c:if test="${asn==policyGroup.groupName }">selected</c:if>><spring:message code="${policyGroup.groupName}"/></option>
</c:forEach>
</select> --%>
<input class="form-control required invisibleChar asnMustExists" type="text" name="userRegion5" value="${_cfg.userRegion5}" ctx="${ctx}">
<input class="form-control required invisibleChar orgMustExists hidden" type="text" name="userRegion4" value="${asn}" ctx="${ctx}">
</div>
<div for="userRegion5"></div>
</div>
</div>
</div>
<br>
</html>

View File

@@ -728,6 +728,8 @@ var showHideIPSECProtocol=function(obj){
<%@include file="/WEB-INF/include/form/areaInfo.jsp"%>
<br>
<%@include file="/WEB-INF/include/form/basicInfo.jsp"%>
<br>
<%@include file="/WEB-INF/include/form/scheduleNew.jsp"%>
<div class="form-actions">
<div class="row">
<div class="col-md-6">

View File

@@ -370,6 +370,8 @@
<th column="block_type" class="sort-column a.action"><spring:message code="block_type"/></th>
<th column="userregion2" ><spring:message code="ratelimit"/></th>
<th column="is_audit" ><spring:message code="is_audit"/></th>
<th column="valid_identifier" class="sort-column a.is_valid"><spring:message code="valid_identifier"/></th>
<th><spring:message code="is_schduler"/></th>
<th column="do_log" ><spring:message code="do_log"/></th>
<th column="do_blacklist" ><spring:message code="do_blacklist"/></th>
<th column="log_total" ><spring:message code="log_total"/></th>
@@ -378,7 +380,6 @@
<th column="classification" ><spring:message code="classification"/></th>
<th column="attribute" ><spring:message code="attribute"/></th>
<th column="label" ><spring:message code="label"/></th>
<th column="valid_identifier" class="sort-column a.is_valid"><spring:message code="valid_identifier"/></th>
<th column="creator" ><spring:message code="creator"/></th>
<th column="config_time" class="sort-column a.create_time"><spring:message code="config_time"/></th>
<th column="editor" ><spring:message code="editor"/></th>
@@ -420,6 +421,25 @@
</c:when>
</c:choose>
</td>
<td>
<c:if test="${indexCfg.isValid==0}"><spring:message code="no"/></c:if>
<c:if test="${indexCfg.isValid==1}"><spring:message code="yes"/></c:if>
<c:if test="${indexCfg.isValid==-1}"><spring:message code="deleted"/></c:if>
</td>
<td class="schedulerFlag">
<c:choose>
<c:when test="${not empty indexCfg.schedule }">
<span isScheduler="yes">
<i class="fa fa-clock-o" style="color:#d9534f;font-size:20px"></i>
</span>
</c:when>
<c:otherwise>
<span isScheduler="no">
</span>
</c:otherwise>
</c:choose>
</td>
<td>
<c:forEach items="${fns:getDictList('DO_LOG') }" var="dict">
<c:if test="${dict.itemCode eq indexCfg.doLog and indexCfg.action!=64 and indexCfg.action!=32}">
@@ -502,11 +522,6 @@
${fns:abbr(lableInfo,20)}
</a>
</td>
<td>
<c:if test="${indexCfg.isValid==0}"><spring:message code="no"/></c:if>
<c:if test="${indexCfg.isValid==1}"><spring:message code="yes"/></c:if>
<c:if test="${indexCfg.isValid==-1}"><spring:message code="deleted"/></c:if>
</td>
<td>${indexCfg.creatorName }</td>
<td><fmt:formatDate value="${indexCfg.createTime }" pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td>${indexCfg.editorName }</td>

View File

@@ -19,6 +19,15 @@
</div>
</c:forEach>
<c:if test="${not empty _cfg.schedule }">
<div id="scheduleTitle${index}" onclick="switchSubCfgTabInfo('schedule',${index})"
class="col-md-1 tabInfo" name="tabTitle${index }">
<spring:message code='schedule' />
<i id="schedule${index}" class="fa" name="tabFlag${index}"></i>
</div>
</c:if>
</div>
<c:forEach items="${tabList}" var="region">
<c:if test="${region[0] eq 1 }">
@@ -245,4 +254,10 @@
</c:forEach>
</c:if>
</c:forEach>
<!-- 显示 定时任务信息 -->
<c:if test="${not empty _cfg.schedule }">
<div id="scheduleInfo${index}" class="content" name="subCfg${index}">
<%@include file="/WEB-INF/include/form/scheduleNewSubList.jsp"%>
</div>
</c:if>
</html>

View File

@@ -0,0 +1 @@
Shawn Chin <shawn.chin__AT__(GEE)mail.com>

View File

@@ -0,0 +1,20 @@
Copyright (c) 2010 Shawn Chin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,40 @@
# jQuery plugin: cron
jquery-cron is a [jQuery] plugin for
presenting a simplified interface for users to specify cron entries.
Check out the [jquery-cron] website for more information.
There is much to be done on the flexibility and robustness front,
and we welcome contributions and bug fixes. Feel free to fork
and send us pull requests!
## Dependencies
* [jQuery]
* [jquery-gentleSelect] (optional)
## Usage
To use this plugin, one simply needs to load [jQuery]
and the JS/CSS scripts for jquery-cron, then attach it an empty `<DIV>`
on DOM ready:
$(document).ready(function() {
$('#selector').cron();
});
</script>
For more options, see the [jquery-cron] website.
## Others
Copyright (c) 2010-2013, Shawn Chin.
This project is licensed under the [MIT license].
[jQuery]: http://jquery.com "jQuery"
[jquery-cron]: http://shawnchin.github.com/jquery-cron "jquery-cron"
[jquery-gentleSelect]: http://shawnchin.github.com/jquery-gentleSelect "jquery-gentleSelect"
[MIT License]: http://www.opensource.org/licenses/mit-license.php "MIT License"

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
.cron-button {
height: 16px;
padding-left: 20px;
margin-left: 5px;
background-repeat: no-repeat;
background-position: center center;
cursor: pointer;
}
.cron-button-save {
background-image: url('img/disk.png');
}
.cron-changed {
padding-top: 5px;
padding-bottom: 5px;
background-color: #fdd;
}
.cron-controls {
margin-left: 10px;
color: #c77;
font-size: 0.9em;
}
.cron-controls > span.cron-loading {
background-image: url('img/loading.gif');
}

View File

@@ -0,0 +1,512 @@
/*
* jQuery gentleSelect plugin (version 0.1.4.1)
* http://shawnchin.github.com/jquery-cron
*
* Copyright (c) 2010-2013 Shawn Chin.
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Requires:
* - jQuery
*
* Usage:
* (JS)
*
* // initialise like this
* var c = $('#cron').cron({
* initial: '9 10 * * *', # Initial value. default = "* * * * *"
* url_set: '/set/', # POST expecting {"cron": "12 10 * * 6"}
* });
*
* // you can update values later
* c.cron("value", "1 2 3 4 *");
*
* // you can also get the current value using the "value" option
* alert(c.cron("value"));
*
* (HTML)
* <div id='cron'></div>
*
* Notes:
* At this stage, we only support a subset of possible cron options.
* For example, each cron entry can only be digits or "*", no commas
* to denote multiple entries. We also limit the allowed combinations:
* - Every minute : * * * * *
* - Every hour : ? * * * *
* - Every day : ? ? * * *
* - Every week : ? ? * * ?
* - Every month : ? ? ? * *
* - Every year : ? ? ? ? *
*/
(function($) {
var defaults = {
initial : "* * * * *",
minuteOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : 30,
columns : 4,
rows : undefined,
title : "Minutes Past the Hour"
},
timeHourOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : 20,
columns : 2,
rows : undefined,
title : "Time: Hour"
},
domOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : 30,
columns : undefined,
rows : 10,
title : "Day of Month"
},
monthOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : 100,
columns : 2,
rows : undefined,
title : undefined
},
dowOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : undefined,
columns : undefined,
rows : undefined,
title : undefined
},
timeMinuteOpts : {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : 20,
columns : 4,
rows : undefined,
title : "Time: Minute"
},
effectOpts : {
openSpeed : 400,
closeSpeed : 400,
openEffect : "slide",
closeEffect : "slide",
hideOnMouseOut : true
},
url_set : undefined,
customValues : undefined,
onChange: undefined, // callback function each time value changes
useGentleSelect: false
};
// ------- build some static data -------
// options for minutes in an hour
var str_opt_mih = "";
for (var i = 0; i < 60; i++) {
var j = (i < 10)? "0":"";
str_opt_mih += "<option value='"+i+"'>" + j + i + "</option>\n";
}
// options for hours in a day
var str_opt_hid = "";
for (var i = 0; i < 24; i++) {
var j = (i < 10)? "0":"";
str_opt_hid += "<option value='"+i+"'>" + j + i + "</option>\n";
}
// options for days of month
var str_opt_dom = "";
for (var i = 1; i < 32; i++) {
if (i == 1 || i == 21 || i == 31) { var suffix = "st"; }
else if (i == 2 || i == 22) { var suffix = "nd"; }
else if (i == 3 || i == 23) { var suffix = "rd"; }
else { var suffix = "th"; }
str_opt_dom += "<option value='"+i+"'>" + i + suffix + "</option>\n";
}
// options for months
var str_opt_month = "";
var months = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"];
for (var i = 0; i < months.length; i++) {
str_opt_month += "<option value='"+(i+1)+"'>" + months[i] + "</option>\n";
}
// options for day of week
var str_opt_dow = "";
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday"];
for (var i = 0; i < days.length; i++) {
str_opt_dow += "<option value='"+i+"'>" + days[i] + "</option>\n";
}
// options for period
var str_opt_period = "";
//var periods = ["minute", "hour", "day", "week", "month", "year"];
var periods = ["day", "week", "month", "year"];
for (var i = 0; i < periods.length; i++) {
str_opt_period += "<option value='"+periods[i]+"'>" + periods[i] + "</option>\n";
}
// display matrix
var toDisplay = {
"minute" : [],
"hour" : ["mins"],
"day" : ["time"],
"week" : ["dow", "time"],
"month" : ["dom", "time"],
"year" : ["dom", "month", "time"]
};
var combinations = {
"minute" : /^(\*\s){4}\*$/, // "* * * * *"
"hour" : /^\d{1,2}\s(\*\s){3}\*$/, // "? * * * *"
"day" : /^(\d{1,2}\s){2}(\*\s){2}\*$/, // "? ? * * *"
"week" : /^(\d{1,2}\s){2}(\*\s){2}\d{1,2}$/, // "? ? * * ?"
"month" : /^(\d{1,2}\s){3}\*\s\*$/, // "? ? ? * *"
"year" : /^(\d{1,2}\s){4}\*$/ // "? ? ? ? *"
};
// ------------------ internal functions ---------------
function defined(obj) {
if (typeof obj == "undefined") { return false; }
else { return true; }
}
function undefinedOrObject(obj) {
return (!defined(obj) || typeof obj == "object")
}
function getCronType(cron_str, opts) {
// if customValues defined, check for matches there first
if (defined(opts.customValues)) {
for (key in opts.customValues) {
if (cron_str == opts.customValues[key]) { return key; }
}
}
// check format of initial cron value
var valid_cron = /^((\d{1,2}|\*)\s){4}(\d{1,2}|\*)$/
if (typeof cron_str != "string" || !valid_cron.test(cron_str)) {
$.error("cron: invalid initial value");
return undefined;
}
// check actual cron values
var d = cron_str.split(" ");
// mm, hh, DD, MM, DOW
var minval = [ 0, 0, 1, 1, 0];
var maxval = [59, 23, 31, 12, 6];
for (var i = 0; i < d.length; i++) {
if (d[i] == "*") continue;
var v = parseInt(d[i]);
if (defined(v) && v <= maxval[i] && v >= minval[i]) continue;
$.error("cron: invalid value found (col "+(i+1)+") in " + o.initial);
return undefined;
}
// determine combination
for (var t in combinations) {
if (combinations[t].test(cron_str)) { return t; }
}
// unknown combination
$.error("cron: valid but unsupported cron format. sorry.");
return undefined;
}
function hasError(c, o) {
if (!defined(getCronType(o.initial, o))) { return true; }
if (!undefinedOrObject(o.customValues)) { return true; }
// ensure that customValues keys do not coincide with existing fields
if (defined(o.customValues)) {
for (key in o.customValues) {
if (combinations.hasOwnProperty(key)) {
$.error("cron: reserved keyword '" + key +
"' should not be used as customValues key.");
return true;
}
}
}
return false;
}
function getCurrentValue(c) {
var b = c.data("block");
var min = hour = day = month = dow = "*";
var selectedPeriod = b["period"].find("select").val();
switch (selectedPeriod) {
case "minute":
break;
case "hour":
min = b["mins"].find("select").val();
break;
case "day":
min = b["time"].find("select.cron-time-min").val();
hour = b["time"].find("select.cron-time-hour").val();
break;
case "week":
min = b["time"].find("select.cron-time-min").val();
hour = b["time"].find("select.cron-time-hour").val();
dow = b["dow"].find("select").val();
break;
case "month":
min = b["time"].find("select.cron-time-min").val();
hour = b["time"].find("select.cron-time-hour").val();
day = b["dom"].find("select").val();
break;
case "year":
min = b["time"].find("select.cron-time-min").val();
hour = b["time"].find("select.cron-time-hour").val();
day = b["dom"].find("select").val();
month = b["month"].find("select").val();
break;
default:
// we assume this only happens when customValues is set
return selectedPeriod;
}
return [min, hour, day, month, dow].join(" ");
}
// ------------------- PUBLIC METHODS -----------------
var methods = {
init : function(opts) {
// init options
var options = opts ? opts : {}; /* default to empty obj */
var o = $.extend([], defaults, options);
var eo = $.extend({}, defaults.effectOpts, options.effectOpts);
$.extend(o, {
minuteOpts : $.extend({}, defaults.minuteOpts, eo, options.minuteOpts),
domOpts : $.extend({}, defaults.domOpts, eo, options.domOpts),
monthOpts : $.extend({}, defaults.monthOpts, eo, options.monthOpts),
dowOpts : $.extend({}, defaults.dowOpts, eo, options.dowOpts),
timeHourOpts : $.extend({}, defaults.timeHourOpts, eo, options.timeHourOpts),
timeMinuteOpts : $.extend({}, defaults.timeMinuteOpts, eo, options.timeMinuteOpts)
});
// error checking
if (hasError(this, o)) { return this; }
// ---- define select boxes in the right order -----
var block = [], custom_periods = "", cv = o.customValues;
if (defined(cv)) { // prepend custom values if specified
for (var key in cv) {
custom_periods += "<option value='" + cv[key] + "'>" + key + "</option>\n";
}
}
block["period"] = $("<span class='cron-period'>"
+ "Every <select name='cron-period'>" + custom_periods
+ str_opt_period + "</select> </span>")
.appendTo(this)
.data("root", this);
var select = block["period"].find("select");
select.bind("change.cron", event_handlers.periodChanged)
.data("root", this);
if (o.useGentleSelect) select.gentleSelect(eo);
block["dom"] = $("<span class='cron-block cron-block-dom'>"
+ " on the <select name='cron-dom'>" + str_opt_dom
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["dom"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.domOpts);
block["month"] = $("<span class='cron-block cron-block-month'>"
+ " of <select name='cron-month'>" + str_opt_month
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["month"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.monthOpts);
block["mins"] = $("<span class='cron-block cron-block-mins'>"
+ " at <select name='cron-mins'>" + str_opt_mih
+ "</select> minutes past the hour </span>")
.appendTo(this)
.data("root", this);
select = block["mins"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.minuteOpts);
block["dow"] = $("<span class='cron-block cron-block-dow'>"
+ " on <select name='cron-dow'>" + str_opt_dow
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["dow"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.dowOpts);
block["time"] = $("<span class='cron-block cron-block-time'>"
+ " at <select name='cron-time-hour' class='cron-time-hour'>" + str_opt_hid
+ "</select>:<select name='cron-time-min' class='cron-time-min'>" + str_opt_mih
+ " </span>")
.appendTo(this)
.data("root", this);
select = block["time"].find("select.cron-time-hour").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.timeHourOpts);
select = block["time"].find("select.cron-time-min").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.timeMinuteOpts);
block["controls"] = $("<span class='cron-controls'>&laquo; save "
+ "<span class='cron-button cron-button-save'></span>"
+ " </span>")
.appendTo(this)
.data("root", this)
.find("span.cron-button-save")
.bind("click.cron", event_handlers.saveClicked)
.data("root", this)
.end();
this.find("select").bind("change.cron-callback", event_handlers.somethingChanged);
this.data("options", o).data("block", block); // store options and block pointer
this.data("current_value", o.initial); // remember base value to detect changes
return methods["value"].call(this, o.initial); // set initial value
},
value : function(cron_str) {
// when no args, act as getter
if (!cron_str) { return getCurrentValue(this); }
var o = this.data('options');
var block = this.data("block");
var useGentleSelect = o.useGentleSelect;
var t = getCronType(cron_str, o);
if (!defined(t)) { return false; }
if (defined(o.customValues) && o.customValues.hasOwnProperty(t)) {
t = o.customValues[t];
} else {
var d = cron_str.split(" ");
var v = {
"mins" : d[0],
"hour" : d[1],
"dom" : d[2],
"month" : d[3],
"dow" : d[4]
};
// update appropriate select boxes
var targets = toDisplay[t];
for (var i = 0; i < targets.length; i++) {
var tgt = targets[i];
if (tgt == "time") {
var btgt = block[tgt].find("select.cron-time-hour").val(v["hour"]);
if (useGentleSelect) btgt.gentleSelect("update");
btgt = block[tgt].find("select.cron-time-min").val(v["mins"]);
if (useGentleSelect) btgt.gentleSelect("update");
} else {;
var btgt = block[tgt].find("select").val(v[tgt]);
if (useGentleSelect) btgt.gentleSelect("update");
}
}
}
// trigger change event
var bp = block["period"].find("select").val(t);
if (useGentleSelect) bp.gentleSelect("update");
bp.trigger("change");
return this;
}
};
var event_handlers = {
periodChanged : function() {
var root = $(this).data("root");
var block = root.data("block"),
opt = root.data("options");
var period = $(this).val();
root.find("span.cron-block").hide(); // first, hide all blocks
if (toDisplay.hasOwnProperty(period)) { // not custom value
var b = toDisplay[$(this).val()];
for (var i = 0; i < b.length; i++) {
block[b[i]].show();
}
}
},
somethingChanged : function() {
root = $(this).data("root");
// if AJAX url defined, show "save"/"reset" button
if (defined(root.data("options").url_set)) {
if (methods.value.call(root) != root.data("current_value")) { // if changed
root.addClass("cron-changed");
root.data("block")["controls"].fadeIn();
} else { // values manually reverted
root.removeClass("cron-changed");
root.data("block")["controls"].fadeOut();
}
} else {
root.data("block")["controls"].hide();
}
// chain in user defined event handler, if specified
var oc = root.data("options").onChange;
if (defined(oc) && $.isFunction(oc)) {
oc.call(root);
}
},
saveClicked : function() {
var btn = $(this);
var root = btn.data("root");
var cron_str = methods.value.call(root);
if (btn.hasClass("cron-loading")) { return; } // in progress
btn.addClass("cron-loading");
$.ajax({
type : "POST",
url : root.data("options").url_set,
data : { "cron" : cron_str },
success : function() {
root.data("current_value", cron_str);
btn.removeClass("cron-loading");
// data changed since "save" clicked?
if (cron_str == methods.value.call(root)) {
root.removeClass("cron-changed");
root.data("block").controls.fadeOut();
}
},
error : function() {
alert("An error occured when submitting your request. Try again?");
btn.removeClass("cron-loading");
}
});
}
};
$.fn.cron = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.cron' );
}
};
})(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
.gentleselect-data { display: none; }
.gentleselect-label {
padding: 1px 20px 1px 20px;
background-color: #eee;
border: 2px solid #ddd;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-repeat: no-repeat;
background-position: center right;
cursor: pointer;
color: #555;
white-space: nowrap;
}
.gentleselect-label-highlight {
border: 2px solid #aaa;
background-image: url('img/expand.png');
}
.gentleselect-dialog {
position: absolute;
z-index: 500;
display: none;
background-color: #fff;
border: 2px solid #999;
-moz-box-shadow: 0px 0px 12px #555;
-webkit-box-shadow: 0px 0px 12px #555;
box-shadow: 0px 0px 12px #555;
margin: 0; padding: 0;
}
.gentleselect-dialog > ul { padding: 0; margin: 0; list-style: none; }
.gentleselect-dialog > ul > li {
margin: 0;
padding: 3px 20px 3px 25px;
cursor: pointer;
}
.gentleselect-dialog > ul > li.selected {
font-weight: bold;
color: #369;
background-color: #eee;
}
.gentleselect-dialog > ul > li.gentleselect-dummy:hover { background-color: #fff; }
.gentleselect-dialog > ul > li:hover {
background-color: #69c;
color: #fff;
}
.gentleselect-dialog > .gentleselect-title {
display: block;
text-align: center;
margin: 0;
padding: 2px;
background-color: #ddd;
font-size: 0.8em;
color: #666;
overflow: hidden;
}

View File

@@ -0,0 +1,300 @@
/*
* jQuery gentleSelect plugin
* http://shawnchin.github.com/jquery-gentleSelect
*
* Copyright (c) 2010 Shawn Chin.
* Licensed under the MIT license.
*
* Usage:
* (JS)
*
* $('#myselect').gentleSelect(); // default. single column
*
* $('#myselect').gentleSelect({ // 3 columns, 150px wide each
* itemWidth : 150,
* columns : 3,
* });
*
* (HTML)
* <select id='myselect'><options> .... </options></select>
*
*/
(function($) {
var defaults = {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : undefined,
columns : undefined,
rows : undefined,
title : undefined,
prompt : "Make A Selection",
maxDisplay: 0, // set to 0 for unlimited
openSpeed : 400,
closeSpeed : 400,
openEffect : "slide",
closeEffect : "slide",
hideOnMouseOut : true
}
function defined(obj) {
if (typeof obj == "undefined") { return false; }
else { return true; }
}
function hasError(c, o) {
if (defined(o.columns) && defined(o.rows)) {
$.error("gentleSelect: You cannot supply both 'rows' and 'columns'");
return true;
}
if (defined(o.columns) && !defined(o.itemWidth)) {
$.error("gentleSelect: itemWidth must be supplied if 'columns' is specified");
return true;
}
if (defined(o.rows) && !defined(o.itemWidth)) {
$.error("gentleSelect: itemWidth must be supplied if 'rows' is specified");
return true;
}
if (!defined(o.openSpeed) || typeof o.openSpeed != "number" &&
(typeof o.openSpeed == "string" && (o.openSpeed != "slow" && o.openSpeed != "fast"))) {
$.error("gentleSelect: openSpeed must be an integer or \"slow\" or \"fast\"");
return true;
}
if (!defined(o.closeSpeed) || typeof o.closeSpeed != "number" &&
(typeof o.closeSpeed == "string" && (o.closeSpeed != "slow" && o.closeSpeed != "fast"))) {
$.error("gentleSelect: closeSpeed must be an integer or \"slow\" or \"fast\"");
return true;
}
if (!defined(o.openEffect) || (o.openEffect != "fade" && o.openEffect != "slide")) {
$.error("gentleSelect: openEffect must be either 'fade' or 'slide'!");
return true;
}
if (!defined(o.closeEffect)|| (o.closeEffect != "fade" && o.closeEffect != "slide")) {
$.error("gentleSelect: closeEffect must be either 'fade' or 'slide'!");
return true;
}
if (!defined(o.hideOnMouseOut) || (typeof o.hideOnMouseOut != "boolean")) {
$.error("gentleSelect: hideOnMouseOut must be supplied and either \"true\" or \"false\"!");
return true;
}
return false;
}
function optionOverrides(c, o) {
if (c.attr("multiple")) {
o.hideOnMouseOut = true; // must be true or dialog will never hide
}
}
function getSelectedAsText(elemList, opts) {
// If no items selected, return prompt
if (elemList.length < 1) { return opts.prompt; }
// Truncate if exceed maxDisplay
if (opts.maxDisplay != 0 && elemList.length > opts.maxDisplay) {
var arr = elemList.slice(0, opts.maxDisplay).map(function(){return $(this).text();});
arr.push("...");
} else {
var arr = elemList.map(function(){return $(this).text();});
}
return arr.get().join(", ");
}
var methods = {
init : function(options) {
var o = $.extend({}, defaults, options);
if (hasError(this, o)) { return this; }; // check for errors
optionOverrides(this, o); //
this.hide(); // hide original select box
// initialise <span> to replace select box
label_text = getSelectedAsText(this.find(":selected"), o);
var label = $("<span class='gentleselect-label'>" + label_text + "</span>")
.insertBefore(this)
.bind("mouseenter.gentleselect", event_handlers.labelHoverIn)
.bind("mouseleave.gentleselect", event_handlers.labelHoverOut)
.bind("click.gentleselect", event_handlers.labelClick)
.data("root", this);
this.data("label", label)
.data("options", o);
// generate list of options
var ul = $("<ul></ul>");
this.find("option").each(function() {
var li = $("<li>" + $(this).text() + "</li>")
.data("value", $(this).attr("value"))
.data("name", $(this).text())
.appendTo(ul);
if ($(this).attr("selected")) { li.addClass("selected"); }
});
// build dialog box
var dialog = $("<div class='gentleselect-dialog'></div>")
.append(ul)
.insertAfter(label)
.bind("click.gentleselect", event_handlers.dialogClick)
.bind("mouseleave.gentleselect", event_handlers.dialogHoverOut)
.data("label", label)
.data("root", this);
this.data("dialog", dialog);
// if to be displayed in columns
if (defined(o.columns) || defined(o.rows)) {
// Update CSS
ul.css("float", "left")
.find("li").width(o.itemWidth).css("float","left");
var f = ul.find("li:first");
var actualWidth = o.itemWidth
+ parseInt(f.css("padding-left"))
+ parseInt(f.css("padding-right"));
var elemCount = ul.find("li").length;
if (defined(o.columns)) {
var cols = parseInt(o.columns);
var rows = Math.ceil(elemCount / cols);
} else {
var rows = parseInt(o.rows);
var cols = Math.ceil(elemCount / rows);
}
dialog.width(actualWidth * cols);
// add padding
for (var i = 0; i < (rows * cols) - elemCount; i++) {
$("<li style='float:left' class='gentleselect-dummy'><span>&nbsp;</span></li>").appendTo(ul);
}
// reorder elements
var ptr = [];
var idx = 0;
ul.find("li").each(function() {
if (idx < rows) {
ptr[idx] = $(this);
} else {
var p = idx % rows;
$(this).insertAfter(ptr[p]);
ptr[p] = $(this);
}
idx++;
});
} else if (typeof o.minWidth == "number") {
dialog.css("min-width", o.minWidth);
}
if (defined(o.title)) {
$("<div class='gentleselect-title'>" + o.title + "</div>").prependTo(dialog);
}
// ESC key should hide all dialog boxes
$(document).bind("keyup.gentleselect", event_handlers.keyUp);
return this;
},
// if select box was updated externally, we need to bring everything
// else up to speed.
update : function() {
var opts = this.data("options");
// Update li with selected data
var v = (this.attr("multiple")) ? this.val() : [this.val()];
$("li", this.data("dialog")).each(function() {
var $li = $(this);
var isSelected = ($.inArray($li.data("value"), v) != -1);
$li.toggleClass("selected", isSelected);
});
// Update label
var label = getSelectedAsText(this.find(":selected"), opts);
this.data("label").text(label);
return this;
}
};
var event_handlers = {
labelHoverIn : function() {
$(this).addClass('gentleselect-label-highlight');
},
labelHoverOut : function() {
$(this).removeClass('gentleselect-label-highlight');
},
labelClick : function() {
var $this = $(this);
var pos = $this.position();
var root = $this.data("root");
var opts = root.data("options");
var dialog = root.data("dialog")
.css("top", pos.top + $this.height())
.css("left", pos.left + 1);
if (opts.openEffect == "fade") {
dialog.fadeIn(opts.openSpeed);
} else {
dialog.slideDown(opts.openSpeed);
}
},
dialogHoverOut : function() {
var $this = $(this);
if ($this.data("root").data("options").hideOnMouseOut) {
$this.hide();
}
},
dialogClick : function(e) {
var clicked = $(e.target);
var $this = $(this);
var root = $this.data("root");
var opts = root.data("options");
if (!root.attr("multiple")) {
if (opts.closeEffect == "fade") {
$this.fadeOut(opts.closeSpeed);
} else {
$this.slideUp(opts.closeSpeed);
}
}
if (clicked.is("li") && !clicked.hasClass("gentleselect-dummy")) {
var value = clicked.data("value");
var name = clicked.data("name");
var label = $this.data("label")
if ($this.data("root").attr("multiple")) {
clicked.toggleClass("selected");
var s = $this.find("li.selected");
label.text(getSelectedAsText(s, opts));
var v = s.map(function(){ return $(this).data("value"); });
// update actual selectbox and trigger change event
root.val(v.get()).trigger("change");
} else {
$this.find("li.selected").removeClass("selected");
clicked.addClass("selected");
label.text(clicked.data("name"));
// update actual selectbox and trigger change event
root.val(value).trigger("change");
}
}
},
keyUp : function(e) {
if (e.keyCode == 27 ) { // ESC
$(".gentleselect-dialog").hide();
}
}
};
$.fn.gentleSelect = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.gentleSelect' );
}
};
})(jQuery);

View File

@@ -0,0 +1,384 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jquery-cron : a jQuery plugin</title>
<link type="text/css" href="gentleSelect/jquery-gentleSelect.css" rel="stylesheet" />
<link type="text/css" href="cron/jquery-cron.css" rel="stylesheet" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="gentleSelect/jquery-gentleSelect-min.js"></script>
<script type="text/javascript" src="cron/jquery-cron.js"></script>
<style>
* { margin: 0; padding: 0; }
body { font-family: Helvetica,Arial,sans-serif; color: #222; background-color: #ddd;line-height: 24px; }
ul { margin-left: 20px; }
ol { margin: 15px 0px 0px 20px; }
ol li { margin-top: 10px; }
h1 { margin: 30px; font-size: 2.5em; font-weight: bold; color: #000; text-align: center; }
h2 { border-bottom: 1px solid #999; margin: 30px 0 10px 0; font-size: 1.3em; color: #555; }
h3 { border-left: 20px solid #999; padding-left: 10px; line-height: 1.2; font-size: 1.1em; color: #333; margin: 30px 0 10px 0; }
p { line-height: 1.3; margin-top: 20px; }
pre { line-height: 1.3; background-color: #369; color: #fff; padding: 10px; margin-top: 20px;}
a { color: #369; font-weight: bold; text-decoration: none; }
a:hover { text-decoration: underline; }
.example { margin: 10px; border: 1px dashed #ccc; padding: 10px;}
.example-text { font-family: monospace; }
#content { margin: 0 auto; padding: 20px 20px 40px 20px; width: 760px; background-color: #fff; border: 1px solid #777; border-width: 0 1px 0px 1px; }
#footer { margin: 0 auto; padding: 20px; padding-top: 2px; width: 760px; font-size: 0.8em; text-align: center; color: #888; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
}
});
$('#example1b').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1b-val').text($(this).cron("value"));
},
useGentleSelect: true
});
$('#example2').cron({
initial: "42 3 * * 5",
effectOpts: {
openEffect: "fade",
openSpeed: "slow"
},
useGentleSelect: true
});
$('#example3').cron({
initial: "*/5 * * * *",
onChange: function() {
$('#example3-val').text($(this).cron("value"));
},
customValues: {
"5 Minutes" : "*/5 * * * *",
"2 Hours on Weekends" : "0 */2 * * 5,6"
},
useGentleSelect: true
});
$('#example4').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example4-val').text($(this).cron("value"));
},
useGentleSelect: true
});
});
</script>
</head>
<body>
<div id="content">
<h1>jQuery plugin: cron</h1>
<h2 id='intro'>Introduction</h2>
<p>
jquery-cron is a <a href='http://jquery.com'>jQuery</a> plugin for
presenting a simplified interface for users to specify cron entries.
</p>
<p>
Instead of having to specify the five elements of a cron entry (minute,
hour, day of month, month, day of week), jquery-cron provides a simpler
interface for users to enter the more common combinations. For example:
</p>
<div class='example'>
<div id='example1'></div>
<p>Generated cron entry: <span class='example-text' id='example1-val'></span></p>
</div>
Or, with <a href='#option-useGentleSelect'>useGentleSelect</a> enabled:
<div class='example'>
<div id='example1b'></div>
<p>Generated cron entry: <span class='example-text' id='example1b-val'></span></p>
</div>
<p>
In addition, the <a href='#option-customvalues'><tt>customValues</tt></a>
option can be used to provide a list of canned cron entries. This allow users to
cater for common use cases as well as enable more complex cron entries.
</p>
<p>
There is much room for improvements and we welcome contributions
and bug fixes. Feel free to fork <a href='https://github.com/shawnchin/jquery-cron'>the project</a>
and send us pull requests!
</p>
<h2>Download</h2>
<ul>
<li>Latest Release : <a href='https://github.com/shawnchin/jquery-cron/zipball/v0.1.4.1'>jquery-cron v0.1.4.1</a></li>
<li>If you're feeling brave, download the <a href='https://github.com/shawnchin/jquery-cron/zipball/master'>Development Version</a></li>
</ul>
<h2>TODO</h2>
<ul>
<li>Support multiple entries per field</li>
<li>implement option to add CSS class (simplify customisation)</li>
<li>make the AJAX POST functionality more generic</li>
</ul>
<h2>Usage</h2>
<p>
To use this plugin, one simply needs to load <a href='http://jquery.com'>jQuery</a>
and the JS/CSS scripts for jquery-cron:
</p>
<pre>
&lt;script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="cron/jquery-cron.js"&gt;&lt;/script&gt;
&lt;link type="text/css" href="cron/jquery-cron.css" rel="stylesheet" /&gt;
</pre>
<p>If used with <a href="#option-useGentleSelect"><tt>useGentleSelect</tt></a> you'll also need:</p>
<pre>
&lt;script type="text/javascript" src="gentleSelect/jquery-gentleSelect.js"&gt;&lt;/script&gt;
&lt;link type="text/css" href="gentleSelect/jquery-gentleSelect.css" rel="stylesheet" /&gt;
</pre>
<p>
then attach it to an empty &lt;div&gt; on DOM ready:
</p>
<pre>
&lt;script type="text/javascript"&gt;
$(document).ready(function() {
$('#selector').cron(); // apply cron with default options
});
&lt;/script&gt;
&lt;!--- somewhere within &lt;body&gt; --&gt;
&lt;div id='selector'&gt;&lt;/div&gt;
</pre>
<p>
There are several ways one can utilise the generated cron entry:
<ol>
<li>
<strong>Interrogating the object</strong> :
See <a href="#method-value"><tt>value</tt></a> method and <a href="#option-onchange"><tt>onChange</tt></a> option.
</li>
<li>
<strong>AJAX POST</strong> :
See the <a href="#option-urlset"><tt>url_set</tt></a> option.
</li>
<li>
<strong>embed in existing form</strong> (not recommended) :
The UI is rendered as a series of &lt;select&gt; boxes within the &lt;div&gt;.
Therefore, one can (in theory) embed the whole &lt;div&gt; within a form and on submission
interrogate the appropriate fields. The generated fiels will have the names:
<ul>
<li><tt>cron-period</tt> : possible values are "minute, hour, day, week, month, year"</li>
<li><tt>cron-mins</tt> : only relevant when cron-period = "hour"</li>
<li><tt>cron-time-hour</tt> : only relevant when cron-period = "day, week, month, year" </li>
<li><tt>cron-time-min</tt> : only relevant when cron-period = "day, week, month, year" </li>
<li><tt>cron-dom</tt> : only relevant when cron-period = "month, year"</li>
<li><tt>cron-month</tt> : only relevant when cron-period = "year"</li>
<li><tt>cron-dow</tt> : only relevant when cron-period = "week"</li>
</ul>
</li>
</ol>
</p>
<h2>Options</h2>
<h3 id='option-initial'>initial</h3>
<p>
The <tt>initial</tt> option allows you the set the initial cron value. If an initialll value is not set,
a default value of <tt>"* * * * *"</tt> is used.
</p>
<p>
After the object has been set up, you can still update the value using
the <a href="#method-value"><tt>value</tt></a> method.
</p>
<h3 id='option-urlset'>url_set</h3>
<p>
You can asynchronously submit the current value to you backend script by specifying then
the URL using the <tt>url_set</tt> option.
</p>
<p>
If this option is set, a "save" icon will appear when changes are made allowing users
to submit their changes to the backend for processing.
</p>
<p>
jquery-cron will submit the values <tt>{"cron": ??}</tt> using a POST request via AJAX.
If a non-error HTTP response is received, the save is considered to be successfule and
the "save" icon will be hidden until the next change is made.
</p>
<h3 id='option-onchange'>onChange</h3>
<p>
You can set a callback function using the <tt>onChange</tt> option. The function will be called
each time the value changes.
For instance, the <a href='#intro'>example in the introduction</a> is implemented as using:
</p>
<pre>
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
}
});</pre>
<h3 id='option-useGentleSelect'>useGentleSelect</h3>
<p>Tells the plugin to use <a href='http://shawnchin.github.com/jquery-gentleSelect'>gentleSelect</a> to show dropdown options instead of the default select inputs.
</p>
<pre>
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
},
useGentleSelect: true // default: false
});</pre>
<div class='example'>
<div id='example4'></div>
<p>Generated cron entry: <span class='example-text' id='example4-val'></span></p>
</div>
<h3 id='option-effectopts'>effectOpts</h3>
<p>
You can change the effects used when displaying/hiding the selection menu by changing the
parameters in effectOpts. These values will be used as the default options for <tt>gentleSelect</tt>.
</p>
<p>
The following parameters can be set:
<ul>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-effect'>openEffect</a> (default: <tt>'slide'</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-effect'>closeEffect</a> (default: <tt>'slide'</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-speed'>openSpeed</a> (default: <tt>400</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-speed'>closeSpeed</a> (default: <tt>400</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-mouseout'>hideOnMouseOut</a> (default: <tt>true</tt>)</li>
</ul>
</p>
<p>
For example, the following uses the <tt>fade</tt> effect with a slower animation speed:
</p>
<p>
<div id='example2'></div>
<pre>
$('#example2').cron({
initial: "42 3 * * 5",
effectOpts: {
openEffect: "fade",
openSpeed: "slow"
}
});</pre>
</p>
<h3 id='option-each-element'>Customising individual select boxes</h3>
<p>
It is possible to customise each of the generated select boxes by sending additional
options to its instance of <tt>gentleSelect</tt>.
All <a href='http://shawnchin.github.com/jquery-gentleSelect/#option-title'>attributes
support by jquery-gentleSelect</a> can be specified.
</p>
<p>
The following are the options to use for each select menu:
<ul>
<li><tt>minuteOpts</tt> - Minutes past the hour (hourly)</li>
<li><tt>timeMinuteOpts</tt> - Time:Minute (daily, weekly, monthly, yearly)</li>
<li><tt>timeHourOpts</tt> - Time:Hour (daily, weekly, monthly, yearly)</li>
<li><tt>dowOpts</tt> - Day of week (weekly)</li>
<li><tt>domOpts</tt> - Day of month (monthly, yearly)</li>
<li><tt>monthOpts</tt> - Month (yearly)</li>
</ul>
</p>
<p>
For example, to change the title of the "Day of Month" select box which appears for monthly and yearly crons:
<pre>
$('#selector').cron({
initial: "42 3 * * 5",
domOpts: {
title: "N-th day of the month"
}
});
</pre>
</p>
<h3 id='option-customvalues'>Adding custom values</h3>
<p>
Additional entries can be included in the period selection using the <tt>customValues</tt>
option. This allows you to specify more complex cron entries that is not currently expressible
using the current setup.
</p>
<p>
For example, the following adds two additional entries to the selection:
<pre>
$('#selector').cron({
initial: "*/5 * * * *",
customValues: {
"5 Minutes" : "*/5 * * * *",
"2 Hours on Weekends" : "0 */2 * * 5,6"
}
});
</pre>
</p>
<div class='example'>
<div id='example3'></div>
<p>Generated cron entry: <span class='example-text' id='example3-val'></span></p>
</div>
<p>
<b>Caveats:</b>
<ul>
<li>
At present, cron entries specified in <tt>customValues</tt> are not validated.
It is down to the implementer to ensure that provided values are as required.
</li>
<li>
The <a href='#method-value'><tt>value</tt></a> method can be used to retrieve
custom cron values. However, it cannot be used to set custom values.
</li>
</ul>
</p>
<h2>Methods</h2>
<h3 id='method-value'>value</h3>
<p>
The <tt>value</tt> method enables you to set/get the current cron value.
</p>
<pre>
// Initialise a cron objecy
var cron_field = $('#selector').cron();
// Updating the value of an existing cron object
cron_field.cron("value", "12 23 * * *");
// calling the method with the extra argument returns the current value
var current_value = cron_field.cron("value")
</pre>
</div>
<div id='footer'>
Copyright &copy; 2010-2013 <a href='http://github.com/shawnchin'>Shawn Chin</a>
(Licensed under the <a href='http://www.opensource.org/licenses/mit-license.php'>MIT License</a>)
</div>
<a href="http://github.com/shawnchin/jquery-cron"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub" /></a>
</body>
</html>