Compare commits
2 Commits
4b536f9777
...
347a329b0a
Author | SHA1 | Date |
---|---|---|
|
347a329b0a | |
|
989cef6f65 |
|
@ -15,7 +15,8 @@ public class MybatisPlusConfig {
|
|||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
|
||||
// 如果配置多个插件, 切记分页最后添加
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.muyu.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author dongzeliang
|
||||
* @version 1.0
|
||||
* @description: 系统逻辑删除
|
||||
* @date 2025/1/16 18:48
|
||||
*/
|
||||
public enum SysDelFlag {
|
||||
// 存在
|
||||
EXIST("0", "存在"),
|
||||
// 删除
|
||||
NOT_EXIST("2", "删除")
|
||||
;
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
SysDelFlag(String code, String info) {
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.muyu.common.core.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author dongzeliang
|
||||
* @version 1.0
|
||||
* @description: 系统开关
|
||||
* @date 2025/1/16 18:44
|
||||
*/
|
||||
@Getter
|
||||
public enum SysNormalDisable {
|
||||
ENABLE("0", "正常"),
|
||||
DISABLE("1", "停用");
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
SysNormalDisable(String code, String info) {
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
* @param code 编码
|
||||
* @return 启用:true 禁用:false
|
||||
*/
|
||||
public static boolean isEnable(String code) {
|
||||
return ENABLE.getCode().equals(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否禁用
|
||||
* @param code 编码
|
||||
* @return 启用:false 禁用:true
|
||||
*/
|
||||
public static boolean isDisable(String code) {
|
||||
return !isEnable(code);
|
||||
}
|
||||
|
||||
}
|
|
@ -338,12 +338,16 @@ public final class HTMLFilter {
|
|||
final List<String> paramNames = new ArrayList<>();
|
||||
final List<String> paramValues = new ArrayList<>();
|
||||
while (m2.find()) {
|
||||
paramNames.add(m2.group(1)); // ([a-z0-9]+)
|
||||
paramValues.add(m2.group(3)); // (.*?)
|
||||
// ([a-z0-9]+)
|
||||
paramNames.add(m2.group(1));
|
||||
// (.*?)
|
||||
paramValues.add(m2.group(3));
|
||||
}
|
||||
while (m3.find()) {
|
||||
paramNames.add(m3.group(1)); // ([a-z0-9]+)
|
||||
paramValues.add(m3.group(3)); // ([^\"\\s']+)
|
||||
// ([a-z0-9]+)
|
||||
paramNames.add(m3.group(1));
|
||||
// ([^\"\\s']+)
|
||||
paramValues.add(m3.group(3));
|
||||
}
|
||||
|
||||
String paramName, paramValue;
|
||||
|
@ -454,8 +458,10 @@ public final class HTMLFilter {
|
|||
// validate entities throughout the string
|
||||
Matcher m = P_VALID_ENTITIES.matcher(s);
|
||||
while (m.find()) {
|
||||
final String one = m.group(1); // ([^&;]*)
|
||||
final String two = m.group(2); // (?=(;|&|$))
|
||||
// ([^&;]*)
|
||||
final String one = m.group(1);
|
||||
// (?=(;|&|$))
|
||||
final String two = m.group(2);
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
|
|
@ -113,4 +113,5 @@ public class SysDept extends BaseEntity {
|
|||
public String getEmail () {
|
||||
return email;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import com.muyu.common.log.enums.BusinessType;
|
|||
import com.muyu.common.security.annotation.RequiresPermissions;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.common.system.domain.SysDept;
|
||||
import com.muyu.system.domain.model.CheckDeptNameUniqueModel;
|
||||
import com.muyu.system.domain.model.SysDeptPageQueryModel;
|
||||
import com.muyu.system.domain.rep.SysDeptAddReq;
|
||||
import com.muyu.system.domain.rep.SysDeptListReq;
|
||||
import com.muyu.system.service.SysDeptService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
@ -70,12 +72,12 @@ public class SysDeptController extends BaseController {
|
|||
@RequiresPermissions("system:dept:add")
|
||||
@Log(title = "部门管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public Result add (@Validated @RequestBody SysDept dept) {
|
||||
if (!deptService.checkDeptNameUnique(dept)) {
|
||||
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
public Result<String> add (@Validated @RequestBody SysDeptAddReq sysDeptAddReq) {
|
||||
if (!deptService.checkDeptNameUnique(CheckDeptNameUniqueModel.of(sysDeptAddReq.getDeptName()))) {
|
||||
return error("新增部门'" + sysDeptAddReq.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
dept.setCreateBy(SecurityUtils.getUsername());
|
||||
return toAjax(deptService.insertDept(dept));
|
||||
deptService.insertDept(sysDeptAddReq.buildSysDept());
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +89,9 @@ public class SysDeptController extends BaseController {
|
|||
public Result edit (@Validated @RequestBody SysDept dept) {
|
||||
Long deptId = dept.getDeptId();
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
if (!deptService.checkDeptNameUnique(dept)) {
|
||||
if (!deptService.checkDeptNameUnique(
|
||||
CheckDeptNameUniqueModel.of(dept.getDeptName(),deptId,dept.getParentId())
|
||||
)) {
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
} else if (dept.getParentId().equals(deptId)) {
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||
|
@ -104,7 +108,7 @@ public class SysDeptController extends BaseController {
|
|||
@RequiresPermissions("system:dept:remove")
|
||||
@Log(title = "部门管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{deptId}")
|
||||
public Result remove (@PathVariable("deptId") Long deptId) {
|
||||
public Result<String> remove (@PathVariable("deptId") Long deptId) {
|
||||
if (deptService.hasChildByDeptId(deptId)) {
|
||||
return warn("存在下级部门,不允许删除");
|
||||
}
|
||||
|
@ -112,6 +116,7 @@ public class SysDeptController extends BaseController {
|
|||
return warn("部门存在用户,不允许删除");
|
||||
}
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return toAjax(deptService.deleteDeptById(deptId));
|
||||
deptService.deleteDeptById(deptId);
|
||||
return success();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package com.muyu.system.domain.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author dongzeliang
|
||||
* @version 1.0
|
||||
* @description: 校验部门名称唯一性模型
|
||||
* @date 2025/1/16 18:18
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CheckDeptNameUniqueModel {
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门ID 若传入部门ID则排除此部门
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 部门父级ID 传入父级ID则只校验子集ID
|
||||
*/
|
||||
private Long parentDeptId;
|
||||
|
||||
/**
|
||||
* 根据部门名称进行唯一性查询模型构建
|
||||
* @param deptName 部门名称
|
||||
* @return 唯一性查询模型
|
||||
*/
|
||||
public static CheckDeptNameUniqueModel of(String deptName){
|
||||
return CheckDeptNameUniqueModel.builder()
|
||||
.deptName(deptName)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门名称进行唯一性查询模型构建
|
||||
* @param deptName 部门名称
|
||||
* @param deptId 部门ID
|
||||
* @return 唯一性查询模型
|
||||
*/
|
||||
public static CheckDeptNameUniqueModel of(String deptName, Long deptId){
|
||||
return CheckDeptNameUniqueModel.builder()
|
||||
.deptName(deptName)
|
||||
.deptId(deptId)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门名称进行唯一性查询模型构建
|
||||
* @param deptName 部门名称
|
||||
* @param deptId 部门ID
|
||||
* @param parentDeptId 部门父级ID
|
||||
* @return 唯一性查询模型
|
||||
*/
|
||||
public static CheckDeptNameUniqueModel of(String deptName, Long deptId, Long parentDeptId){
|
||||
return CheckDeptNameUniqueModel.builder()
|
||||
.deptName(deptName)
|
||||
.deptId(deptId)
|
||||
.parentDeptId(parentDeptId)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.muyu.system.domain.rep;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.common.system.domain.SysDept;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author dongzeliang
|
||||
* @version 1.0
|
||||
* @description: 部门管理添加请求对象
|
||||
* @date 2025/1/16 18:06
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysDeptAddReq {
|
||||
|
||||
/**
|
||||
* 父部门ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
private String leader;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 部门状态:0正常,1停用
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 2代表删除)
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
public SysDept buildSysDept(){
|
||||
return SysDept.builder()
|
||||
.deptName(this.deptName)
|
||||
.orderNum(this.orderNum)
|
||||
.email(this.email)
|
||||
.delFlag(this.delFlag)
|
||||
.phone(this.phone)
|
||||
.status(this.status)
|
||||
.leader(this.leader)
|
||||
.parentId(this.parentId)
|
||||
.createBy(SecurityUtils.getUsername())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.muyu.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muyu.common.system.domain.SysDept;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -31,23 +32,6 @@ public interface SysDeptMapper extends BaseMapper<SysDept> {
|
|||
*/
|
||||
public List<Long> selectDeptListByRoleId (@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
|
||||
|
||||
/**
|
||||
* 根据部门ID查询信息
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
*
|
||||
* @return 部门信息
|
||||
*/
|
||||
public SysDept selectDeptById (Long deptId);
|
||||
|
||||
/**
|
||||
* 根据ID查询所有子部门
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
*
|
||||
* @return 部门列表
|
||||
*/
|
||||
public List<SysDept> selectChildrenDeptById (Long deptId);
|
||||
|
||||
/**
|
||||
* 根据ID查询所有子部门(正常状态)
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.muyu.system.service;
|
|||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muyu.common.system.domain.SysDept;
|
||||
import com.muyu.system.domain.model.CheckDeptNameUniqueModel;
|
||||
import com.muyu.system.domain.model.SysDeptPageQueryModel;
|
||||
import com.muyu.system.domain.vo.TreeSelect;
|
||||
|
||||
|
@ -95,11 +96,10 @@ public interface SysDeptService extends IService<SysDept> {
|
|||
/**
|
||||
* 校验部门名称是否唯一
|
||||
*
|
||||
* @param dept 部门信息
|
||||
*
|
||||
* @param checkDeptNameUniqueModel 部门信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean checkDeptNameUnique (SysDept dept);
|
||||
public boolean checkDeptNameUnique (CheckDeptNameUniqueModel checkDeptNameUniqueModel);
|
||||
|
||||
/**
|
||||
* 校验部门是否有数据权限
|
||||
|
@ -115,7 +115,7 @@ public interface SysDeptService extends IService<SysDept> {
|
|||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertDept (SysDept dept);
|
||||
public void insertDept (SysDept dept);
|
||||
|
||||
/**
|
||||
* 修改保存部门信息
|
||||
|
@ -133,7 +133,7 @@ public interface SysDeptService extends IService<SysDept> {
|
|||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteDeptById (Long deptId);
|
||||
public void deleteDeptById (Long deptId);
|
||||
|
||||
/**
|
||||
* 查询部门信息
|
||||
|
@ -141,4 +141,13 @@ public interface SysDeptService extends IService<SysDept> {
|
|||
* @return 分页返回结果
|
||||
*/
|
||||
List<SysDept> queryList(SysDeptPageQueryModel sysDeptPageQueryModel);
|
||||
|
||||
/**
|
||||
* 根据ID查询所有子部门
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
*
|
||||
* @return 部门列表
|
||||
*/
|
||||
public List<SysDept> selectChildrenDeptById (Long deptId);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.muyu.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.muyu.common.core.constant.UserConstants;
|
||||
import com.muyu.common.core.enums.SysDelFlag;
|
||||
import com.muyu.common.core.enums.SysNormalDisable;
|
||||
import com.muyu.common.core.exception.ServiceException;
|
||||
import com.muyu.common.core.text.Convert;
|
||||
import com.muyu.common.core.utils.SpringUtils;
|
||||
|
@ -12,6 +15,7 @@ import com.muyu.common.security.utils.SecurityUtils;
|
|||
import com.muyu.common.system.domain.SysDept;
|
||||
import com.muyu.common.system.domain.SysRole;
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
import com.muyu.system.domain.model.CheckDeptNameUniqueModel;
|
||||
import com.muyu.system.domain.model.SysDeptPageQueryModel;
|
||||
import com.muyu.system.domain.vo.TreeSelect;
|
||||
import com.muyu.system.mapper.SysDeptMapper;
|
||||
|
@ -19,6 +23,7 @@ import com.muyu.system.mapper.SysRoleMapper;
|
|||
import com.muyu.system.service.SysDeptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -45,6 +50,7 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.like(StringUtils.isNotEmpty(sysDeptPageQueryModel.getDeptName()),SysDept::getDeptName, sysDeptPageQueryModel.getDeptName());
|
||||
queryWrapper.eq(StringUtils.isNotEmpty(sysDeptPageQueryModel.getStatus()),SysDept::getStatus,sysDeptPageQueryModel.getStatus());
|
||||
queryWrapper.eq(SysDept::getStatus, SysDelFlag.EXIST.getCode());
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
|
@ -141,7 +147,7 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
*/
|
||||
@Override
|
||||
public SysDept selectDeptById (Long deptId) {
|
||||
return deptMapper.selectDeptById(deptId);
|
||||
return this.getById(deptId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,14 +191,19 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
/**
|
||||
* 校验部门名称是否唯一
|
||||
*
|
||||
* @param dept 部门信息
|
||||
*
|
||||
* @param checkDeptNameUniqueModel 检查模型
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkDeptNameUnique (SysDept dept) {
|
||||
Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId();
|
||||
SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId());
|
||||
public boolean checkDeptNameUnique (CheckDeptNameUniqueModel checkDeptNameUniqueModel) {
|
||||
Assert.notNull(checkDeptNameUniqueModel.getDeptName(), "部门名称不可为空");
|
||||
LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDept::getDeptName, checkDeptNameUniqueModel.getDeptName());
|
||||
queryWrapper.eq(Objects.nonNull(checkDeptNameUniqueModel.getParentDeptId()), SysDept::getParentId, checkDeptNameUniqueModel.getParentDeptId());
|
||||
queryWrapper.eq(SysDept::getStatus, SysDelFlag.EXIST.getCode());
|
||||
|
||||
Long deptId = StringUtils.isNull(checkDeptNameUniqueModel.getDeptId()) ? -1L : checkDeptNameUniqueModel.getDeptId();
|
||||
SysDept info = deptMapper.checkDeptNameUnique(checkDeptNameUniqueModel.getDeptName(), checkDeptNameUniqueModel.getParentDeptId());
|
||||
if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) {
|
||||
return UserConstants.NOT_UNIQUE;
|
||||
}
|
||||
|
@ -207,9 +218,9 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
@Override
|
||||
public void checkDeptDataScope (Long deptId) {
|
||||
if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
|
||||
List<SysDept> depts = SpringUtils.getAopProxy(this)
|
||||
List<SysDept> deptList = SpringUtils.getAopProxy(this)
|
||||
.selectDeptList(SysDeptPageQueryModel.ofToDeptId(deptId));
|
||||
if (StringUtils.isEmpty(depts)) {
|
||||
if (StringUtils.isEmpty(deptList)) {
|
||||
throw new ServiceException("没有权限访问部门数据!");
|
||||
}
|
||||
}
|
||||
|
@ -223,14 +234,14 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertDept (SysDept dept) {
|
||||
SysDept info = deptMapper.selectDeptById(dept.getParentId());
|
||||
public void insertDept (SysDept dept) {
|
||||
SysDept parentSysDept = this.getById(dept.getParentId());
|
||||
// 如果父节点不为正常状态,则不允许新增子节点
|
||||
if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
|
||||
if (SysNormalDisable.isDisable(dept.getStatus())) {
|
||||
throw new ServiceException("部门停用,不允许新增");
|
||||
}
|
||||
dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
|
||||
return deptMapper.insertDept(dept);
|
||||
dept.setAncestors(parentSysDept.getAncestors() + "," + dept.getParentId());
|
||||
this.save(dept);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,8 +253,8 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
*/
|
||||
@Override
|
||||
public int updateDept (SysDept dept) {
|
||||
SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId());
|
||||
SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId());
|
||||
SysDept newParentDept = this.getById(dept.getParentId());
|
||||
SysDept oldDept = this.getById(dept.getDeptId());
|
||||
if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) {
|
||||
String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
|
||||
String oldAncestors = oldDept.getAncestors();
|
||||
|
@ -278,7 +289,7 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
* @param oldAncestors 旧的父ID集合
|
||||
*/
|
||||
public void updateDeptChildren (Long deptId, String newAncestors, String oldAncestors) {
|
||||
List<SysDept> children = deptMapper.selectChildrenDeptById(deptId);
|
||||
List<SysDept> children = this.selectChildrenDeptById(deptId);
|
||||
for (SysDept child : children) {
|
||||
child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
|
||||
}
|
||||
|
@ -295,8 +306,11 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteDeptById (Long deptId) {
|
||||
return deptMapper.deleteDeptById(deptId);
|
||||
public void deleteDeptById (Long deptId) {
|
||||
LambdaUpdateWrapper<SysDept> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.set(SysDept::getStatus, SysDelFlag.NOT_EXIST.getCode());
|
||||
updateWrapper.eq(SysDept::getDeptId, deptId);
|
||||
this.update(updateWrapper);
|
||||
}
|
||||
|
||||
|
||||
|
@ -334,4 +348,17 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
|
|||
private boolean hasChild (List<SysDept> list, SysDept t) {
|
||||
return !getChildList(list, t).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询所有子部门
|
||||
*
|
||||
* @param deptId 部门ID
|
||||
*
|
||||
* @return 部门列表
|
||||
*/
|
||||
public List<SysDept> selectChildrenDeptById (Long deptId){
|
||||
LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.apply("FIND_IN_SET('" + deptId + "', type)");
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,8 +289,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
*/
|
||||
@Override
|
||||
public boolean updateRoleStatus (SysRole role) {
|
||||
boolean updateResult = updateById(role); // 通过 roleId 更新角色信息
|
||||
return updateResult;
|
||||
// 通过 roleId 更新角色信息
|
||||
return updateById(role);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,7 +303,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean authDataScope (SysRole role) {
|
||||
// 修改角色信息
|
||||
boolean updateResult = updateById(role); // 通过 roleId 更新角色信息
|
||||
// 通过 roleId 更新角色信息
|
||||
boolean updateResult = updateById(role);
|
||||
// 删除角色与部门关联
|
||||
roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId());
|
||||
// 新增角色和部门信息(数据权限)
|
||||
|
@ -332,7 +333,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
// 使用MyBatis-Plus的saveBatch方法批量插入角色与菜单的关联关系
|
||||
boolean saveResult = roleMenuMapper.saveBatch(list);
|
||||
|
||||
return saveResult ? list.size() : 0; // 返回成功插入的数量
|
||||
// 返回成功插入的数量
|
||||
return saveResult ? list.size() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,11 +70,6 @@
|
|||
order by d.parent_id, d.order_num
|
||||
</select>
|
||||
|
||||
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
|
||||
<include refid="selectDeptVo"/>
|
||||
where dept_id = #{deptId}
|
||||
</select>
|
||||
|
||||
<select id="checkDeptExistUser" parameterType="Long" resultType="int">
|
||||
select count(1)
|
||||
from sys_user
|
||||
|
@ -90,12 +85,6 @@
|
|||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectChildrenDeptById" parameterType="Long" resultMap="SysDeptResult">
|
||||
select *
|
||||
from sys_dept
|
||||
where find_in_set(#{deptId}, ancestors)
|
||||
</select>
|
||||
|
||||
<select id="selectNormalChildrenDeptById" parameterType="Long" resultType="int">
|
||||
select count(*)
|
||||
from sys_dept
|
||||
|
|
|
@ -46,18 +46,23 @@ public class JobInfoController {
|
|||
public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) {
|
||||
|
||||
// 枚举-字典
|
||||
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表
|
||||
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典
|
||||
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典
|
||||
model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型
|
||||
model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略
|
||||
// 路由策略-列表
|
||||
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());
|
||||
// Glue类型-字典
|
||||
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());
|
||||
// 阻塞处理策略-字典
|
||||
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values());
|
||||
// 调度类型
|
||||
model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values());
|
||||
// 调度过期策略
|
||||
model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values());
|
||||
|
||||
// 执行器列表
|
||||
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
|
||||
List<XxlJobGroup> jobGroupList1 = xxlJobGroupDao.findAll();
|
||||
|
||||
// filter group
|
||||
List<XxlJobGroup> jobGroupList = PermissionInterceptor.filterJobGroupByRole(request, jobGroupList_all);
|
||||
if (jobGroupList==null || jobGroupList.size()==0) {
|
||||
List<XxlJobGroup> jobGroupList = PermissionInterceptor.filterJobGroupByRole(request, jobGroupList1);
|
||||
if (jobGroupList==null || jobGroupList.isEmpty()) {
|
||||
throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
|
||||
}
|
||||
|
||||
|
|
|
@ -94,13 +94,13 @@ public class JobLogController {
|
|||
@RequestParam(required = false, defaultValue = "10") int length,
|
||||
int jobGroup, int jobId, int logStatus, String filterTime) {
|
||||
|
||||
// valid permission
|
||||
PermissionInterceptor.validJobGroupPermission(request, jobGroup); // 仅管理员支持查询全部;普通用户仅支持查询有权限的 jobGroup
|
||||
// valid permission 仅管理员支持查询全部;普通用户仅支持查询有权限的 jobGroup
|
||||
PermissionInterceptor.validJobGroupPermission(request, jobGroup);
|
||||
|
||||
// parse param
|
||||
Date triggerTimeStart = null;
|
||||
Date triggerTimeEnd = null;
|
||||
if (filterTime!=null && filterTime.trim().length()>0) {
|
||||
if (filterTime!=null && !filterTime.trim().isEmpty()) {
|
||||
String[] temp = filterTime.split(" - ");
|
||||
if (temp.length == 2) {
|
||||
triggerTimeStart = DateUtil.parseDateTime(temp[0]);
|
||||
|
@ -114,9 +114,12 @@ public class JobLogController {
|
|||
|
||||
// package result
|
||||
Map<String, Object> maps = new HashMap<String, Object>();
|
||||
maps.put("recordsTotal", list_count); // 总记录数
|
||||
maps.put("recordsFiltered", list_count); // 过滤后的总记录数
|
||||
maps.put("data", list); // 分页列表
|
||||
// 总记录数
|
||||
maps.put("recordsTotal", list_count);
|
||||
// 过滤后的总记录数
|
||||
maps.put("recordsFiltered", list_count);
|
||||
// 分页列表
|
||||
maps.put("data", list);
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
@ -141,9 +144,10 @@ public class JobLogController {
|
|||
public ReturnT<LogResult> logDetailCat(long logId, int fromLineNum){
|
||||
try {
|
||||
// valid
|
||||
XxlJobLog jobLog = xxlJobLogDao.load(logId); // todo, need to improve performance
|
||||
// todo, need to improve performance
|
||||
XxlJobLog jobLog = xxlJobLogDao.load(logId);
|
||||
if (jobLog == null) {
|
||||
return new ReturnT<LogResult>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_logid_unvalid"));
|
||||
return new ReturnT<>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_logid_unvalid"));
|
||||
}
|
||||
|
||||
// log cat
|
||||
|
@ -191,7 +195,7 @@ public class JobLogController {
|
|||
runResult = executorBiz.kill(new KillParam(jobInfo.getId()));
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
runResult = new ReturnT<String>(500, e.getMessage());
|
||||
runResult = new ReturnT<>(500, e.getMessage());
|
||||
}
|
||||
|
||||
if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
|
||||
|
@ -199,9 +203,9 @@ public class JobLogController {
|
|||
log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():""));
|
||||
log.setHandleTime(new Date());
|
||||
XxlJobCompleter.updateHandleInfoAndFinish(log);
|
||||
return new ReturnT<String>(runResult.getMsg());
|
||||
return new ReturnT<>(runResult.getMsg());
|
||||
} else {
|
||||
return new ReturnT<String>(500, runResult.getMsg());
|
||||
return new ReturnT<>(500, runResult.getMsg());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,34 +219,43 @@ public class JobLogController {
|
|||
Date clearBeforeTime = null;
|
||||
int clearBeforeNum = 0;
|
||||
if (type == 1) {
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -1); // 清理一个月之前日志数据
|
||||
// 清理一个月之前日志数据
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -1);
|
||||
} else if (type == 2) {
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -3); // 清理三个月之前日志数据
|
||||
// 清理三个月之前日志数据
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -3);
|
||||
} else if (type == 3) {
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -6); // 清理六个月之前日志数据
|
||||
// 清理六个月之前日志数据
|
||||
clearBeforeTime = DateUtil.addMonths(new Date(), -6);
|
||||
} else if (type == 4) {
|
||||
clearBeforeTime = DateUtil.addYears(new Date(), -1); // 清理一年之前日志数据
|
||||
// 清理一年之前日志数据
|
||||
clearBeforeTime = DateUtil.addYears(new Date(), -1);
|
||||
} else if (type == 5) {
|
||||
clearBeforeNum = 1000; // 清理一千条以前日志数据
|
||||
// 清理一千条以前日志数据
|
||||
clearBeforeNum = 1000;
|
||||
} else if (type == 6) {
|
||||
clearBeforeNum = 10000; // 清理一万条以前日志数据
|
||||
// 清理一万条以前日志数据
|
||||
clearBeforeNum = 10000;
|
||||
} else if (type == 7) {
|
||||
clearBeforeNum = 30000; // 清理三万条以前日志数据
|
||||
// 清理三万条以前日志数据
|
||||
clearBeforeNum = 30000;
|
||||
} else if (type == 8) {
|
||||
clearBeforeNum = 100000; // 清理十万条以前日志数据
|
||||
// 清理十万条以前日志数据
|
||||
clearBeforeNum = 100000;
|
||||
} else if (type == 9) {
|
||||
clearBeforeNum = 0; // 清理所有日志数据
|
||||
// 清理所有日志数据
|
||||
clearBeforeNum = 0;
|
||||
} else {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_clean_type_unvalid"));
|
||||
return new ReturnT<>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_clean_type_unvalid"));
|
||||
}
|
||||
|
||||
List<Long> logIds = null;
|
||||
do {
|
||||
logIds = xxlJobLogDao.findClearLogIds(jobGroup, jobId, clearBeforeTime, clearBeforeNum, 1000);
|
||||
if (logIds!=null && logIds.size()>0) {
|
||||
if (logIds!=null && !logIds.isEmpty()) {
|
||||
xxlJobLogDao.clearLog(logIds);
|
||||
}
|
||||
} while (logIds!=null && logIds.size()>0);
|
||||
} while (logIds!=null && !logIds.isEmpty());
|
||||
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -65,9 +65,12 @@ public class JobUserController {
|
|||
|
||||
// package result
|
||||
Map<String, Object> maps = new HashMap<String, Object>();
|
||||
maps.put("recordsTotal", list_count); // 总记录数
|
||||
maps.put("recordsFiltered", list_count); // 过滤后的总记录数
|
||||
maps.put("data", list); // 分页列表
|
||||
// 总记录数
|
||||
maps.put("recordsTotal", list_count);
|
||||
// 过滤后的总记录数
|
||||
maps.put("recordsFiltered", list_count);
|
||||
// 分页列表
|
||||
maps.put("data", list);
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
|
|||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true; // proceed with the next interceptor
|
||||
// proceed with the next interceptor
|
||||
return true;
|
||||
}
|
||||
|
||||
// if need login
|
||||
|
@ -54,10 +55,12 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
|
|||
if (needAdminuser && loginUser.getRole()!=1) {
|
||||
throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
|
||||
}
|
||||
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); // set loginUser, with request
|
||||
// set loginUser, with request
|
||||
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
|
||||
}
|
||||
|
||||
return true; // proceed with the next interceptor
|
||||
// proceed with the next interceptor
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,8 +73,8 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
|
|||
* @return
|
||||
*/
|
||||
public static XxlJobUser getLoginUser(HttpServletRequest request){
|
||||
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); // get loginUser, with request
|
||||
return loginUser;
|
||||
// get loginUser, with request
|
||||
return (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,13 +99,13 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
|
|||
*/
|
||||
public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request, List<XxlJobGroup> jobGroupList_all){
|
||||
List<XxlJobGroup> jobGroupList = new ArrayList<>();
|
||||
if (jobGroupList_all!=null && jobGroupList_all.size()>0) {
|
||||
if (jobGroupList_all!=null && !jobGroupList_all.isEmpty()) {
|
||||
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
|
||||
if (loginUser.getRole() == 1) {
|
||||
jobGroupList = jobGroupList_all;
|
||||
} else {
|
||||
List<String> groupIdStrs = new ArrayList<>();
|
||||
if (loginUser.getPermission()!=null && loginUser.getPermission().trim().length()>0) {
|
||||
if (loginUser.getPermission()!=null && !loginUser.getPermission().trim().isEmpty()) {
|
||||
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
|
||||
}
|
||||
for (XxlJobGroup groupItem:jobGroupList_all) {
|
||||
|
|
|
@ -118,7 +118,8 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
|
|||
|
||||
public int getLogretentiondays() {
|
||||
if (logretentiondays < 7) {
|
||||
return -1; // Limit greater than or equal to 7, otherwise close
|
||||
// Limit greater than or equal to 7, otherwise close
|
||||
return -1;
|
||||
}
|
||||
return logretentiondays;
|
||||
}
|
||||
|
|
|
@ -1425,9 +1425,9 @@ public final class CronExpression implements Serializable, Cloneable {
|
|||
}
|
||||
|
||||
} else if (nthdayOfWeek != 0) {
|
||||
// are we looking for the Nth XXX day in the month?
|
||||
int dow = daysOfWeek.first(); // desired
|
||||
// d-o-w // current d-o-w
|
||||
// are we looking for the Nth XXX day in the month? desired
|
||||
int dow = daysOfWeek.first();
|
||||
// d-o-w current d-o-w
|
||||
int cDow = cl.get(Calendar.DAY_OF_WEEK);
|
||||
int daysToAdd = 0;
|
||||
if (cDow < dow) {
|
||||
|
|
|
@ -13,12 +13,14 @@ public class XxlJobGroup {
|
|||
private int id;
|
||||
private String appname;
|
||||
private String title;
|
||||
private int addressType; // 执行器地址类型:0=自动注册、1=手动录入
|
||||
private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
|
||||
// 执行器地址类型:0=自动注册、1=手动录入
|
||||
private int addressType;
|
||||
// 执行器地址列表,多地址逗号分隔(手动录入)
|
||||
private String addressList;
|
||||
private Date updateTime;
|
||||
|
||||
// registry list
|
||||
private List<String> registryList; // 执行器地址列表(系统注册)
|
||||
// registry list // 执行器地址列表(系统注册)
|
||||
private List<String> registryList;
|
||||
public List<String> getRegistryList() {
|
||||
if (addressList!=null && addressList.trim().length()>0) {
|
||||
registryList = new ArrayList<String>(Arrays.asList(addressList.split(",")));
|
||||
|
|
|
@ -8,39 +8,57 @@ import java.util.Date;
|
|||
* @author xuxueli 2016-1-12 18:25:49
|
||||
*/
|
||||
public class XxlJobInfo {
|
||||
|
||||
private int id; // 主键ID
|
||||
|
||||
private int jobGroup; // 执行器主键ID
|
||||
// 主键ID
|
||||
private int id;
|
||||
// 执行器主键ID
|
||||
private int jobGroup;
|
||||
private String jobDesc;
|
||||
|
||||
private Date addTime;
|
||||
private Date updateTime;
|
||||
// 负责人
|
||||
private String author;
|
||||
// 报警邮件
|
||||
private String alarmEmail;
|
||||
|
||||
private String author; // 负责人
|
||||
private String alarmEmail; // 报警邮件
|
||||
// 调度类型
|
||||
private String scheduleType;
|
||||
// 调度配置,值含义取决于调度类型
|
||||
private String scheduleConf;
|
||||
// 调度过期策略
|
||||
private String misfireStrategy;
|
||||
|
||||
private String scheduleType; // 调度类型
|
||||
private String scheduleConf; // 调度配置,值含义取决于调度类型
|
||||
private String misfireStrategy; // 调度过期策略
|
||||
// 执行器路由策略
|
||||
private String executorRouteStrategy;
|
||||
// 执行器,任务Handler名称
|
||||
private String executorHandler;
|
||||
// 执行器,任务参数
|
||||
private String executorParam;
|
||||
// 阻塞处理策略
|
||||
private String executorBlockStrategy;
|
||||
// 任务执行超时时间,单位秒
|
||||
private int executorTimeout;
|
||||
// 失败重试次数
|
||||
private int executorFailRetryCount;
|
||||
|
||||
private String executorRouteStrategy; // 执行器路由策略
|
||||
private String executorHandler; // 执行器,任务Handler名称
|
||||
private String executorParam; // 执行器,任务参数
|
||||
private String executorBlockStrategy; // 阻塞处理策略
|
||||
private int executorTimeout; // 任务执行超时时间,单位秒
|
||||
private int executorFailRetryCount; // 失败重试次数
|
||||
// GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
|
||||
private String glueType;
|
||||
// GLUE源代码
|
||||
private String glueSource;
|
||||
// GLUE备注
|
||||
private String glueRemark;
|
||||
// GLUE更新时间
|
||||
private Date glueUpdatetime;
|
||||
|
||||
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
|
||||
private String glueSource; // GLUE源代码
|
||||
private String glueRemark; // GLUE备注
|
||||
private Date glueUpdatetime; // GLUE更新时间
|
||||
// 子任务ID,多个逗号分隔
|
||||
private String childJobId;
|
||||
|
||||
private String childJobId; // 子任务ID,多个逗号分隔
|
||||
|
||||
private int triggerStatus; // 调度状态:0-停止,1-运行
|
||||
private long triggerLastTime; // 上次调度时间
|
||||
private long triggerNextTime; // 下次调度时间
|
||||
// 调度状态:0-停止,1-运行
|
||||
private int triggerStatus;
|
||||
// 上次调度时间
|
||||
private long triggerLastTime;
|
||||
// 下次调度时间
|
||||
private long triggerNextTime;
|
||||
|
||||
|
||||
public int getId() {
|
||||
|
|
|
@ -9,8 +9,10 @@ import java.util.Date;
|
|||
public class XxlJobLogGlue {
|
||||
|
||||
private int id;
|
||||
private int jobId; // 任务主键ID
|
||||
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
|
||||
// 任务主键ID
|
||||
private int jobId;
|
||||
// GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
|
||||
private String glueType;
|
||||
private String glueSource;
|
||||
private String glueRemark;
|
||||
private Date addTime;
|
||||
|
|
|
@ -8,10 +8,14 @@ import org.springframework.util.StringUtils;
|
|||
public class XxlJobUser {
|
||||
|
||||
private int id;
|
||||
private String username; // 账号
|
||||
private String password; // 密码
|
||||
private int role; // 角色:0-普通用户、1-管理员
|
||||
private String permission; // 权限:执行器ID列表,多个逗号分割
|
||||
// 账号
|
||||
private String username;
|
||||
// 密码
|
||||
private String password;
|
||||
// 角色:0-普通用户、1-管理员
|
||||
private int role;
|
||||
// 权限:执行器ID列表,多个逗号分割
|
||||
private String permission;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
|
|
@ -40,7 +40,8 @@ public class ExecutorRouteLFU extends ExecutorRouter {
|
|||
// put new
|
||||
for (String address: addressList) {
|
||||
if (!lfuItemMap.containsKey(address) || lfuItemMap.get(address) >1000000 ) {
|
||||
lfuItemMap.put(address, new Random().nextInt(addressList.size())); // 初始化时主动Random一次,缓解首次压力
|
||||
// 初始化时主动Random一次,缓解首次压力
|
||||
lfuItemMap.put(address, new Random().nextInt(addressList.size()));
|
||||
}
|
||||
}
|
||||
// remove old
|
||||
|
|
|
@ -27,7 +27,8 @@ public class JobScheduleHelper {
|
|||
return instance;
|
||||
}
|
||||
|
||||
public static final long PRE_READ_MS = 5000; // pre read
|
||||
// pre read
|
||||
public static final long PRE_READ_MS = 5000;
|
||||
|
||||
private Thread scheduleThread;
|
||||
private Thread ringThread;
|
||||
|
@ -311,7 +312,8 @@ public class JobScheduleHelper {
|
|||
// 1、stop schedule
|
||||
scheduleThreadToStop = true;
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(1); // wait
|
||||
// wait
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
@ -371,7 +373,8 @@ public class JobScheduleHelper {
|
|||
if (ScheduleTypeEnum.CRON == scheduleTypeEnum) {
|
||||
Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime);
|
||||
return nextValidTime;
|
||||
} else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) {
|
||||
/*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/
|
||||
} else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum ) {
|
||||
return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 );
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -62,8 +62,9 @@ public class JobTriggerPoolHelper {
|
|||
|
||||
|
||||
// job timeout count
|
||||
private volatile long minTim = System.currentTimeMillis()/60000; // ms > min
|
||||
private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
|
||||
// ms > min
|
||||
private final ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
|
||||
private volatile long minTim = System.currentTimeMillis()/60000;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -77,14 +78,15 @@ public class JobTriggerPoolHelper {
|
|||
final String addressList) {
|
||||
|
||||
// choose thread pool
|
||||
ThreadPoolExecutor triggerPool_ = fastTriggerPool;
|
||||
ThreadPoolExecutor triggerPool = fastTriggerPool;
|
||||
AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId);
|
||||
if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min
|
||||
triggerPool_ = slowTriggerPool;
|
||||
// job-timeout 10 times in 1 min
|
||||
if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) {
|
||||
triggerPool = slowTriggerPool;
|
||||
}
|
||||
|
||||
// trigger
|
||||
triggerPool_.execute(new Runnable() {
|
||||
triggerPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
|
@ -98,9 +100,9 @@ public class JobTriggerPoolHelper {
|
|||
} finally {
|
||||
|
||||
// check timeout-count-map
|
||||
long minTim_now = System.currentTimeMillis()/60000;
|
||||
if (minTim != minTim_now) {
|
||||
minTim = minTim_now;
|
||||
long minTimNow = System.currentTimeMillis()/60000;
|
||||
if (minTim != minTimNow) {
|
||||
minTim = minTimNow;
|
||||
jobTimeoutCountMap.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,10 @@ public class XxlJobTrigger {
|
|||
private static void processTrigger(XxlJobGroup group, XxlJobInfo jobInfo, int finalFailRetryCount, TriggerTypeEnum triggerType, int index, int total){
|
||||
|
||||
// param
|
||||
ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), ExecutorBlockStrategyEnum.SERIAL_EXECUTION); // block strategy
|
||||
ExecutorRouteStrategyEnum executorRouteStrategyEnum = ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null); // route strategy
|
||||
// block strategy
|
||||
ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), ExecutorBlockStrategyEnum.SERIAL_EXECUTION);
|
||||
// route strategy
|
||||
ExecutorRouteStrategyEnum executorRouteStrategyEnum = ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null);
|
||||
String shardingParam = (ExecutorRouteStrategyEnum.SHARDING_BROADCAST==executorRouteStrategyEnum)?String.valueOf(index).concat("/").concat(String.valueOf(total)):null;
|
||||
|
||||
// 1、save log-id
|
||||
|
|
|
@ -54,9 +54,12 @@ public class XxlJobServiceImpl implements XxlJobService {
|
|||
|
||||
// package result
|
||||
Map<String, Object> maps = new HashMap<String, Object>();
|
||||
maps.put("recordsTotal", list_count); // 总记录数
|
||||
maps.put("recordsFiltered", list_count); // 过滤后的总记录数
|
||||
maps.put("data", list); // 分页列表
|
||||
// 总记录数
|
||||
maps.put("recordsTotal", list_count);
|
||||
// 过滤后的总记录数
|
||||
maps.put("recordsFiltered", list_count);
|
||||
// 分页列表
|
||||
maps.put("data", list);
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
@ -84,12 +87,13 @@ public class XxlJobServiceImpl implements XxlJobService {
|
|||
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid"));
|
||||
}
|
||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
||||
/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/
|
||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE) {
|
||||
if (jobInfo.getScheduleConf() == null) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")) );
|
||||
}
|
||||
try {
|
||||
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
|
||||
int fixSecond = Integer.parseInt(jobInfo.getScheduleConf());
|
||||
if (fixSecond < 1) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
|
||||
}
|
||||
|
@ -192,12 +196,13 @@ public class XxlJobServiceImpl implements XxlJobService {
|
|||
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid") );
|
||||
}
|
||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
||||
/*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/
|
||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE) {
|
||||
if (jobInfo.getScheduleConf() == null) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
|
||||
}
|
||||
try {
|
||||
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
|
||||
int fixSecond = Integer.parseInt(jobInfo.getScheduleConf());
|
||||
if (fixSecond < 1) {
|
||||
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
|
||||
}
|
||||
|
|
|
@ -68,7 +68,8 @@ public class XxlJobContext {
|
|||
this.shardIndex = shardIndex;
|
||||
this.shardTotal = shardTotal;
|
||||
|
||||
this.handleCode = HANDLE_CODE_SUCCESS; // default success
|
||||
// default success
|
||||
this.handleCode = HANDLE_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
public long getJobId() {
|
||||
|
@ -109,7 +110,8 @@ public class XxlJobContext {
|
|||
|
||||
// ---------------------- tool ----------------------
|
||||
|
||||
private static InheritableThreadLocal<XxlJobContext> contextHolder = new InheritableThreadLocal<XxlJobContext>(); // support for child thread of job handler)
|
||||
// support for child thread of job handler)
|
||||
private static InheritableThreadLocal<XxlJobContext> contextHolder = new InheritableThreadLocal<XxlJobContext>();
|
||||
|
||||
public static void setXxlJobContext(XxlJobContext xxlJobContext){
|
||||
contextHolder.set(xxlJobContext);
|
||||
|
|
|
@ -144,16 +144,17 @@ public class XxlJobExecutor {
|
|||
|
||||
// fill ip port
|
||||
port = port>0?port: NetUtil.findAvailablePort(9999);
|
||||
ip = (ip!=null&&ip.trim().length()>0)?ip: IpUtil.getIp();
|
||||
ip = (ip!=null&& !ip.trim().isEmpty())?ip: IpUtil.getIp();
|
||||
|
||||
// generate address
|
||||
if (address==null || address.trim().length()==0) {
|
||||
String ip_port_address = IpUtil.getIpPort(ip, port); // registry-address:default use address to registry , otherwise use ip:port if address is null
|
||||
address = "http://{ip_port}/".replace("{ip_port}", ip_port_address);
|
||||
if (address==null || address.trim().isEmpty()) {
|
||||
// registry-address:default use address to registry , otherwise use ip:port if address is null
|
||||
String ipPortAddress = IpUtil.getIpPort(ip, port);
|
||||
address = "http://{ip_port}/".replace("{ip_port}", ipPortAddress);
|
||||
}
|
||||
|
||||
// accessToken
|
||||
if (accessToken==null || accessToken.trim().length()==0) {
|
||||
if (accessToken==null || accessToken.trim().isEmpty()) {
|
||||
logger.warn(">>>>>>>>>>> xxl-job accessToken is empty. To ensure system security, please set the accessToken.");
|
||||
}
|
||||
|
||||
|
@ -245,7 +246,8 @@ public class XxlJobExecutor {
|
|||
newJobThread.start();
|
||||
logger.info(">>>>>>>>>>> xxl-job regist JobThread success, jobId:{}, handler:{}", new Object[]{jobId, handler});
|
||||
|
||||
JobThread oldJobThread = jobThreadRepository.put(jobId, newJobThread); // putIfAbsent | oh my god, map's put method return the old value!!!
|
||||
// putIfAbsent | oh my god, map's put method return the old value!!!
|
||||
JobThread oldJobThread = jobThreadRepository.put(jobId, newJobThread);
|
||||
if (oldJobThread != null) {
|
||||
oldJobThread.toStop(removeOldReason);
|
||||
oldJobThread.interrupt();
|
||||
|
|
|
@ -96,7 +96,8 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
|||
}
|
||||
|
||||
// filter method
|
||||
Map<Method, XxlJob> annotatedMethods = null; // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
|
||||
// referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
|
||||
Map<Method, XxlJob> annotatedMethods = null;
|
||||
try {
|
||||
annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
|
||||
new MethodIntrospector.MetadataLookup<XxlJob>() {
|
||||
|
|
|
@ -26,7 +26,8 @@ public class MethodJobHandler extends IJobHandler {
|
|||
public void execute() throws Exception {
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes.length > 0) {
|
||||
method.invoke(target, new Object[paramTypes.length]); // method-param can not be primitive-types
|
||||
// method-param can not be primitive-types
|
||||
method.invoke(target, new Object[paramTypes.length]);
|
||||
} else {
|
||||
method.invoke(target);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,8 @@ public class XxlJobFileAppender {
|
|||
public static String makeLogFileName(Date triggerDate, long logId) {
|
||||
|
||||
// filePath/yyyy-MM-dd
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // avoid concurrent problem, can not be static
|
||||
// avoid concurrent problem, can not be static
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
File logFilePath = new File(getLogPath(), sdf.format(triggerDate));
|
||||
if (!logFilePath.exists()) {
|
||||
logFilePath.mkdir();
|
||||
|
@ -157,7 +158,8 @@ public class XxlJobFileAppender {
|
|||
String line = null;
|
||||
|
||||
while ((line = reader.readLine())!=null) {
|
||||
toLineNum = reader.getLineNumber(); // [from, to], start as 1
|
||||
// [from, to], start as 1
|
||||
toLineNum = reader.getLineNumber();
|
||||
if (toLineNum >= fromLineNum) {
|
||||
logContentBuffer.append(line).append("\n");
|
||||
}
|
||||
|
|
|
@ -27,16 +27,18 @@ import java.util.concurrent.*;
|
|||
public class JobThread extends Thread{
|
||||
private static Logger logger = LoggerFactory.getLogger(JobThread.class);
|
||||
|
||||
private int jobId;
|
||||
private IJobHandler handler;
|
||||
private LinkedBlockingQueue<TriggerParam> triggerQueue;
|
||||
private Set<Long> triggerLogIdSet; // avoid repeat trigger for the same TRIGGER_LOG_ID
|
||||
private final int jobId;
|
||||
private final IJobHandler handler;
|
||||
private final LinkedBlockingQueue<TriggerParam> triggerQueue;
|
||||
// avoid repeat trigger for the same TRIGGER_LOG_ID
|
||||
private final Set<Long> triggerLogIdSet;
|
||||
|
||||
private volatile boolean toStop = false;
|
||||
private String stopReason;
|
||||
|
||||
private boolean running = false; // if running job
|
||||
private int idleTimes = 0; // idel times
|
||||
// if running job
|
||||
private boolean running = false;
|
||||
// idel times
|
||||
private int idleTimes = 0;
|
||||
|
||||
|
||||
public JobThread(int jobId, IJobHandler handler) {
|
||||
|
@ -184,7 +186,8 @@ public class JobThread extends Thread{
|
|||
|
||||
} else {
|
||||
if (idleTimes > 30) {
|
||||
if(triggerQueue.size() == 0) { // avoid concurrent trigger causes jobId-lost
|
||||
// avoid concurrent trigger causes jobId-lost
|
||||
if(triggerQueue.size() == 0) {
|
||||
XxlJobExecutor.removeJobThread(jobId, "excutor idel times over limit.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,8 @@ public class TriggerCallbackThread {
|
|||
public void toStop(){
|
||||
toStop = true;
|
||||
// stop callback, interrupt and wait
|
||||
if (triggerCallbackThread != null) { // support empty admin address
|
||||
// support empty admin address
|
||||
if (triggerCallbackThread != null) {
|
||||
triggerCallbackThread.interrupt();
|
||||
try {
|
||||
triggerCallbackThread.join();
|
||||
|
|
|
@ -101,7 +101,8 @@ public class ScriptUtil {
|
|||
errThread.start();
|
||||
|
||||
// process-wait
|
||||
int exitValue = process.waitFor(); // exit code: 0=success, 1=error
|
||||
// exit code: 0=success, 1=error
|
||||
int exitValue = process.waitFor();
|
||||
|
||||
// log-thread join
|
||||
inputThread.join();
|
||||
|
|
Loading…
Reference in New Issue