工程管理

This commit is contained in:
cwchen 2024-03-11 20:05:56 +08:00
parent 6bb95e995c
commit 062655df96
16 changed files with 454 additions and 39 deletions

View File

@ -131,7 +131,11 @@
<artifactId>hutool-all</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
package com.securitycontrol.common.core.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/**
* @author cw chen
* @description hibernate-validator
* @date 2023-09-14 17:52
*/
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
//快速失败返回模式
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
}
/**
* 开启快速返回
* 如果参数校验有异常直接抛异常不会进入到 controller使用全局异常拦截进行拦截
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor =
new MethodValidationPostProcessor();
/**设置validator模式为快速失败返回*/
postProcessor.setValidator(validator());
return postProcessor;
}
}

View File

@ -13,4 +13,9 @@ public class Constant {
public final static Integer MENU_TYPE = 2;
public final static String MANGER = "管理员";
public final static Integer SUCCESS = 200;
public final static String MSG = "msg";
public final static String CODE = "code";
}

View File

@ -0,0 +1,100 @@
package com.securitycontrol.common.core.utils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
/**
* @description: <br/>
* 通用Server validation方法
* <p>
* <br/>
* @author: Qz1997
* @create 2021/2/9 14:41
*/
@SuppressWarnings("unused")
@Component(value = "ValidatorsUtils")
public final class ValidatorsUtils {
@Resource
private Validator validator;
/**
* 验证实体
*
* @param obj 实体
* @param <T> 实体类类型
* @return 结果
*/
public <T> String valid(T obj) {
return this.valid(obj, new Class<?>[]{});
}
/**
* 验证实体
*
* @param obj 实体
* @param group 实体组
* @param <T> 实体类类型
* @return 结果
*/
public <T> String valid(T obj, Class<?>... group) {
Set<ConstraintViolation<T>> violations;
if (ArrayUtils.isEmpty(group)) {
violations = validator.validate(obj);
} else {
violations = validator.validate(obj, group);
}
if (CollectionUtils.isNotEmpty(violations)) {
for (ConstraintViolation<T> constraintViolation : violations) {
return constraintViolation.getMessage();
}
}
return null;
}
/**
* 校验list
*
* @param objList list
* @param <T> 实体类类型
* @return 结果
*/
public <T> String validList(List<T> objList) {
return this.validList(objList, new Class<?>[]{});
}
/**
* 校验list
*
* @param objList list
* @param group
* @param <T> 实体类类型
* @return 结果
*/
public <T> String validList(List<T> objList, Class<?>... group) {
if (CollectionUtils.isEmpty(objList)) {
return "对象空";
}
String result;
for (T t : objList) {
if (ArrayUtils.isEmpty(group)) {
result = this.valid(t);
} else {
result = this.valid(t, group);
}
if (!StringUtils.isBlank(result)) {
return result;
}
}
return null;
}
}

View File

@ -2,6 +2,9 @@ package com.securitycontrol.entity.system.base.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
@ -32,6 +35,8 @@ public class ProVo {
private String proCode;
@ApiModelProperty(value = "工程名称")
@NotBlank(message = "工程名称不能为空", groups = {Query.class})
@Length(max = 50, message = "工程名称字符长度不能超过50", groups = {Query.class})
private String proName;
@ApiModelProperty(value = "工程成本")
@ -85,4 +90,9 @@ public class ProVo {
@ApiModelProperty(value = "类型")
private boolean flag;
/**
* 查询条件限制
*/
public interface Query {
}
}

View File

@ -1,6 +1,8 @@
package com.securitycontrol.common.log.aspect;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.securitycontrol.common.core.constant.Constant;
import com.securitycontrol.common.core.utils.ServletUtils;
import com.securitycontrol.common.core.utils.aes.DateTimeHelper;
import com.securitycontrol.common.core.utils.ip.IpUtils;
@ -126,6 +128,9 @@ public class OperLogAspect {
getControllerMethodDescription(joinPoint, aopLog, sysLog);
//利用是否有异常定性记录失败信息
String result = JSON.toJSONString(jsonResult);
JSONObject jsonObject = JSON.parseObject(result);
System.err.println(result);
if (e != null) {
//失败
sysLog.setResult(BusinessStatus.FAIL.ordinal());
@ -143,8 +148,20 @@ public class OperLogAspect {
sysLog.getParams());
log.error("==控制层方法通知异常==");
log.error("异常信息:{}", e.getMessage());
}else if(e == null && !Objects.equals(Integer.parseInt(jsonObject.getString(Constant.CODE)), Constant.SUCCESS)){
sysLog.setResult(BusinessStatus.FAIL.ordinal());
sysLog.setFailureReason(StringUtils.substring(jsonObject.getString("msg"), 0, 2000));
log.error("耗时:{} 用户id:{} 用户名username: {} 请求ip:{} User-Agent:{} 方法路径:{} 方法参数:{}",
sysLog.getTimes(),
sysLog.getUserId(),
sysLog.getOperaUserName(),
sysLog.getIp(),
null,
methodName,
sysLog.getParams());
log.error("==控制层方法通知异常==");
log.error("异常信息:{}", jsonObject.getString(Constant.MSG));
}
log.info(JSON.toJSONString(sysLog));
// 保存数据库
log.info("耗时:{} 用户id:{} 用户名username: {} 请求ip:{} User-Agent:{} 方法路径:{} 方法参数:{}",
sysLog.getTimes(),
@ -229,8 +246,10 @@ public class OperLogAspect {
params.append(jsonObj.toString()).append(" ");
}
} else {
Object jsonObj = JSON.toJSON(value);
params.append(jsonObj.toString()).append(" ");
if(value != null){
Object jsonObj = JSON.toJSON(value);
params.append(jsonObj.toString()).append(" ");
}
}
}
}

View File

@ -0,0 +1,41 @@
package com.securitycontrol.common.security.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/**
* @author cw chen
* @description hibernate-validator
* @date 2023-09-14 17:52
*/
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
//快速失败返回模式
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
}
/**
* 开启快速返回
* 如果参数校验有异常直接抛异常不会进入到 controller使用全局异常拦截进行拦截
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor =
new MethodValidationPostProcessor();
/**设置validator模式为快速失败返回*/
postProcessor.setValidator(validator());
return postProcessor;
}
}

View File

@ -1,6 +1,9 @@
package com.securitycontrol.common.security.handler;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
@ -17,6 +20,8 @@ import com.securitycontrol.common.core.exception.auth.NotRoleException;
import com.securitycontrol.common.core.utils.StringUtils;
import com.securitycontrol.common.core.web.domain.AjaxResult;
import java.util.Set;
/**
* 全局异常处理器
*

View File

@ -6,6 +6,8 @@ import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Objects;
/**
* @authorcwchen
* @date2024-03-01-15:07
@ -13,17 +15,31 @@ import java.io.IOException;
* @description过滤器处理request
*/
@WebFilter
public class MyFilter implements Filter{
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
if (servletRequest instanceof HttpServletRequest && !isFileUpload(request)) {
requestWrapper = new XssRequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
if (requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
public static final String[] EXCLUDE_URLS = {"/sys/pro/addPro"};
public boolean isFileUpload(HttpServletRequest request) {
for (String excludeUrl : EXCLUDE_URLS) {
if (Objects.equals(excludeUrl, request.getRequestURI())) {
return true;
}
}
return false;
}
}

View File

@ -18,7 +18,7 @@ import com.securitycontrol.common.security.utils.XssRequestWrapper;
import com.securitycontrol.system.api.RemoteLogService;
import com.securitycontrol.system.api.RemoteUserService;
import com.securitycontrol.system.api.domain.SysLog;
import com.securitycontrol.system.api.domain.SysOperLog;
import com.securitycontrol.system.api.domain.decision.SysMenu;
import com.securitycontrol.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@ -60,8 +60,24 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
// IResourceService resourceService = (IResourceService) AdapterFactory.getInstance(Constants.CLASS_RESOURCE);
public static final String[] EXCLUDE_URLS = {"/sys/pro/addPro"};
public boolean isFileUpload(HttpServletRequest request) {
for (String excludeUrl : EXCLUDE_URLS) {
if (Objects.equals(excludeUrl, request.getRequestURI())) {
return true;
}
}
return false;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 过滤文件上传功能
if(isFileUpload(request)){
return true;
}
System.out.println("进入了拦截器");
System.err.println(request.getRequestURI());
XssRequestWrapper requestWrapper = new XssRequestWrapper(request);
@ -149,43 +165,71 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
* 判断是否越权
*/
private boolean checkIsYq(HttpServletRequest request, XssRequestWrapper requestWrapper) throws Exception {
String requestURI = request.getRequestURI();
String[] headUrls = requestURI.split("/");
String requestUri = request.getRequestURI();
String[] headUrls = requestUri.split("/");
String url = "/" + headUrls[1] + "/" + headUrls[2];
Boolean result = true;
Boolean result = false;
// String token = requestWrapper.getParameter("token");
String token = SecurityUtils.getToken(request);
if (StringUtils.isNotEmpty(token)) {
// String userId = JwtUtils.getIscUserId(token);
String userId = JwtUtils.getUserId(token);
System.out.println("拦截器userId:" + userId);
if (StringUtil.isEmpty(userId)) {
result = false;
} else {
if (StringUtil.isNotEmpty(userId)) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getSysUser() != null) {
if(CollectionUtils.isNotEmpty(loginUser.getSysUser().getMenus())){
if (CollectionUtils.isNotEmpty(loginUser.getSysUser().getMenus())) {
List<SysMenu> menuList = loginUser.getSysUser().getMenus();
List<SysMenu> sysMenus = treeToList(menuList);
for (SysMenu sysMenu : sysMenus) {
if (Objects.equals(sysMenu.getUrl(), url)) {
result = true;
}
}
}
}else{
// return false;
}
// result = resourceService.hasPermitURLObj(userId, "9b4483c383538275018615493e1451ea", url);
}
// result = resourceService.hasPermitURLObj(userId, "9b4483c383538275018615493e1451ea", url);
System.out.println("==================越狱记录:========================userId:" + userId + "============是否越狱:" + result);
} else {
result = false;
}
if (!result) {
addExceedsAccessLog(url, token);
return false;
// return false;
//添加弹框
}
return true;
}
public List<SysMenu> treeToList(List<SysMenu> treeList) {
List<SysMenu> resList = new ArrayList<>();
Stack<List<SysMenu>> stack = new Stack<>();
for (SysMenu sysMenu : treeList) {
resList.add(beanCopy(sysMenu));
if (sysMenu.getChilder() != null && !sysMenu.getChilder().isEmpty()) {
stack.push(sysMenu.getChilder());
}
}
while (!stack.isEmpty()) {
List<SysMenu> subTree = stack.pop();
for (SysMenu menu : subTree) {
if (menu.getChilder() != null && !menu.getChilder().isEmpty()) {
stack.push(menu.getChilder());
} else {
resList.add(beanCopy(menu));
}
}
}
System.out.println(JSON.toJSONString(resList));
return resList;
}
private SysMenu beanCopy(SysMenu source) {
SysMenu res = new SysMenu();
res.setMenuId(source.getMenuId());
res.setMenuName(source.getMenuName());
res.setUrl(source.getUrl());
return res;
}
private void addExceedsAccessLog(String url, String token) {
SysLog sysLog = new SysLog();
String id = UUID.randomUUID().toString().replaceAll("-", "");

View File

@ -0,0 +1,100 @@
package com.securitycontrol.common.security.utils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
/**
* @description: <br/>
* 通用Server validation方法
* <p>
* <br/>
* @author: Qz1997
* @create 2021/2/9 14:41
*/
@SuppressWarnings("unused")
@Component(value = "ValidatorsUtils")
public final class ValidatorsUtils {
@Resource
private Validator validator;
/**
* 验证实体
*
* @param obj 实体
* @param <T> 实体类类型
* @return 结果
*/
public <T> String valid(T obj) {
return this.valid(obj, new Class<?>[]{});
}
/**
* 验证实体
*
* @param obj 实体
* @param group 实体组
* @param <T> 实体类类型
* @return 结果
*/
public <T> String valid(T obj, Class<?>... group) {
Set<ConstraintViolation<T>> violations;
if (ArrayUtils.isEmpty(group)) {
violations = validator.validate(obj);
} else {
violations = validator.validate(obj, group);
}
if (CollectionUtils.isNotEmpty(violations)) {
for (ConstraintViolation<T> constraintViolation : violations) {
return constraintViolation.getMessage();
}
}
return null;
}
/**
* 校验list
*
* @param objList list
* @param <T> 实体类类型
* @return 结果
*/
public <T> String validList(List<T> objList) {
return this.validList(objList, new Class<?>[]{});
}
/**
* 校验list
*
* @param objList list
* @param group
* @param <T> 实体类类型
* @return 结果
*/
public <T> String validList(List<T> objList, Class<?>... group) {
if (CollectionUtils.isEmpty(objList)) {
return "对象空";
}
String result;
for (T t : objList) {
if (ArrayUtils.isEmpty(group)) {
result = this.valid(t);
} else {
result = this.valid(t, group);
}
if (!StringUtils.isBlank(result)) {
return result;
}
}
return null;
}
}

View File

@ -3,4 +3,7 @@ com.securitycontrol.common.security.service.TokenService
com.securitycontrol.common.security.aspect.PreAuthorizeAspect
com.securitycontrol.common.security.aspect.InnerAuthAspect
com.securitycontrol.common.security.handler.GlobalExceptionHandler
com.securitycontrol.common.security.utils.ValidatorsUtils
com.securitycontrol.common.security.interceptor.MyFilter

View File

@ -5,14 +5,19 @@ import com.securitycontrol.common.core.web.domain.AjaxResult;
import com.securitycontrol.common.core.web.page.TableDataInfo;
import com.securitycontrol.common.log.annotation.Log;
import com.securitycontrol.common.log.enums.OperationType;
import com.securitycontrol.common.security.utils.XssRequestWrapper;
import com.securitycontrol.entity.system.base.dto.ProDto;
import com.securitycontrol.entity.system.base.dto.ProGxPlanDto;
import com.securitycontrol.entity.system.base.vo.ProVo;
import com.securitycontrol.system.base.service.IProService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
@ -41,15 +46,18 @@ public class ProController extends BaseController {
@ApiOperation(value = "新增工程")
@PostMapping("addPro")
@Log(title = "基础管理", menu = "基础管理->工程管理", grade = OperationType.ADD_BUSINESS, details = "新增工程", type = "业务日志")
public AjaxResult addPro(@Valid @RequestBody ProVo vo) {
return service.addOrUpdatePro(vo);
public AjaxResult addPro(HttpServletRequest request, @RequestParam(value = "file[]", required = false) MultipartFile[] files, @RequestParam(value = "type[]", required = false) int[] types,String params) {
return service.addOrUpdatePro(files,types,params);
}
@ApiOperation(value = "修改工程")
@PostMapping("editPro")
@Log(title = "基础管理", menu = "基础管理->工程管理", grade = OperationType.UPDATE_BUSINESS, details = "修改工程", type = "业务日志")
public AjaxResult editPro(@Valid @RequestBody ProVo vo) {
return service.addOrUpdatePro(vo);
public AjaxResult editPro(HttpServletRequest request, @RequestParam(value = "file[]", required = false) MultipartFile[] files, @RequestParam(value = "type[]", required = false) int[] types) {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
MultipartHttpServletRequest multiReq = multipartResolver.resolveMultipart(request);
String params = multiReq.getParameter("params");
return service.addOrUpdatePro(files,types,params);
}
@ApiOperation(value = "工程详情")

View File

@ -4,6 +4,7 @@ import com.securitycontrol.common.core.web.domain.AjaxResult;
import com.securitycontrol.entity.system.base.dto.ProDto;
import com.securitycontrol.entity.system.base.dto.ProGxPlanDto;
import com.securitycontrol.entity.system.base.vo.ProVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@ -28,14 +29,15 @@ public interface IProService {
/**
* 新增/修改工程
*
* @param vo
* @param files
* @param types
* @param params
* @return AjaxResult
* @description
* @description 新增/修改工程
* @author cwchen
* @date 2024/3/11 14:01
* @date 2024/3/11 16:31
*/
AjaxResult addOrUpdatePro(ProVo vo);
AjaxResult addOrUpdatePro(MultipartFile[] files, int[] types, String params);
/**
* 工程详情
@ -61,6 +63,7 @@ public interface IProService {
/**
* 删除工程工序计划
*
* @param dto
* @return AjaxResult
* @description
@ -68,4 +71,5 @@ public interface IProService {
* @date 2024/3/11 14:47
*/
AjaxResult delProGxPlan(ProGxPlanDto dto);
}

View File

@ -1,20 +1,25 @@
package com.securitycontrol.system.base.service.impl;
import com.alibaba.fastjson2.JSON;
import com.securitycontrol.common.core.utils.StringUtils;
import com.securitycontrol.common.core.web.domain.AjaxResult;
import com.securitycontrol.common.security.utils.ValidatorsUtils;
import com.securitycontrol.entity.system.base.dto.ProDto;
import com.securitycontrol.entity.system.base.dto.ProGxPlanDto;
import com.securitycontrol.entity.system.base.vo.ProVo;
import com.securitycontrol.system.base.mapper.IProMapper;
import com.securitycontrol.system.base.service.IProService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @authorcwchen
@ -29,6 +34,10 @@ public class ProServiceImpl implements IProService {
@Resource(name = "IProMapper")
private IProMapper mapper;
@Resource(name = "ValidatorsUtils")
private ValidatorsUtils validatorsUtils;
@Override
public List<ProVo> getProLists(ProDto dto) {
List<ProVo> list = new ArrayList<>();
@ -43,12 +52,18 @@ public class ProServiceImpl implements IProService {
@Override
@Transactional(rollbackFor = Exception.class)
public AjaxResult addOrUpdatePro(ProVo vo) {
public AjaxResult addOrUpdatePro(MultipartFile[] files, int[] types, String params) {
try {
ProVo vo = JSON.parseObject(params, ProVo.class);
String validResult = validatorsUtils.valid(vo, ProVo.Query.class);
if (StringUtils.isNotBlank(validResult)) {
return AjaxResult.error(validResult);
}
if (StringUtils.isBlank(vo.getProId())) {
vo.setType(1);
vo.setProId(UUID.randomUUID().toString().replace("-", ""));
} else {
vo.setType(2);
}
mapper.addOrUpdatePro(vo);
} catch (Exception e) {

View File

@ -29,9 +29,9 @@ public class MongoConfig {
@Value("${spring.data.mongodb.port}")
private Integer port;
private static final String UN = "zhlydb";
private static final String UN = "zhgd";
private static final String PD = "Bonus%40admin123!";
private static final String PD = "Bonus%40admin123";
private MongoDatabase mongoDatabase;