diff --git a/system/src/main/java/com/canvas/web/modules/logging/annotation/Log.java b/system/src/main/java/com/canvas/web/modules/logging/annotation/Log.java new file mode 100644 index 0000000..473c8d3 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/annotation/Log.java @@ -0,0 +1,15 @@ +package com.canvas.web.modules.logging.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Log { + + String value() default ""; + +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/aspect/LogAspect.java b/system/src/main/java/com/canvas/web/modules/logging/aspect/LogAspect.java new file mode 100644 index 0000000..08f1d2a --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/aspect/LogAspect.java @@ -0,0 +1,15 @@ +package com.canvas.web.modules.logging.aspect; + + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + + +@Component +@Aspect +@Slf4j +public class LogAspect { + + +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/domain/Log.java b/system/src/main/java/com/canvas/web/modules/logging/domain/Log.java new file mode 100644 index 0000000..749d746 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/domain/Log.java @@ -0,0 +1,65 @@ +package com.canvas.web.modules.logging.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + + +@Getter +@Setter +@Table(name = "sys_log") +@NoArgsConstructor +public class Log implements Serializable { + + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + //操作用户 + private String username; + + //描述 + private String description; + + //方法名 + private String method; + + //参数 + private String params; + + //日志类型 + private String logType; + + //请求ip + private String requestIp; + + //地址 + private String address; + + //浏览器 + private String browser; + + //请求耗时 + private Long time; + + //异常详细 + private byte[] exceptionDetail; + + //创建日期 + @CreationTimestamp + private Timestamp createTime; + + + public Log(String logType, Long time) { + this.logType = logType; + this.time = time; + } + + +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/repository/LogRepository.java b/system/src/main/java/com/canvas/web/modules/logging/repository/LogRepository.java new file mode 100644 index 0000000..acf6bbf --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/repository/LogRepository.java @@ -0,0 +1,15 @@ +package com.canvas.web.modules.logging.repository; + +import com.canvas.web.modules.logging.domain.Log; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +public interface LogRepository extends JpaRepository, JpaSpecificationExecutor { + + + @Modifying + @Query(value = "delete from sys_log where log_type = ?1",nativeQuery = true) + void deleteByLogType(String logType); +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/LogService.java b/system/src/main/java/com/canvas/web/modules/logging/service/LogService.java new file mode 100644 index 0000000..c2c95fd --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/LogService.java @@ -0,0 +1,27 @@ +package com.canvas.web.modules.logging.service; + +import com.canvas.web.modules.logging.domain.Log; +import com.canvas.web.modules.logging.service.dto.LogQueryCriteria; +import org.aspectj.lang.ProceedingJoinPoint; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; + +import java.util.List; + +public interface LogService { + + Object queryAll(LogQueryCriteria criteria, Pageable pageable); + + List queryAll(LogQueryCriteria criteria); + + Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable); + + @Async + void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log); + + Object findByErrDetail(Long id); + + void delAllByError(); + + void delAllByInfo(); +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogErrorDTO.java b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogErrorDTO.java new file mode 100644 index 0000000..9c906fc --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogErrorDTO.java @@ -0,0 +1,28 @@ +package com.canvas.web.modules.logging.service.dto; + +import lombok.Data; + +import java.sql.Timestamp; + + +@Data +public class LogErrorDTO { + + private Long id; + + private String username; + + private String description; + + private String method; + + private String params; + + private String browser; + + private String requestIp; + + private String address; + + private Timestamp createTime; +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogQueryCriteria.java b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogQueryCriteria.java new file mode 100644 index 0000000..cbacceb --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogQueryCriteria.java @@ -0,0 +1,21 @@ +package com.canvas.web.modules.logging.service.dto; + + +import com.canvas.web.annotation.Query; +import lombok.Data; + +import java.sql.Timestamp; +import java.util.List; + +@Data +public class LogQueryCriteria { + + @Query(blurry = "username,description,address,requestIp,method,params") + private String blurry; + + @Query + private String logType; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogSmallDTO.java b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogSmallDTO.java new file mode 100644 index 0000000..58109b3 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/dto/LogSmallDTO.java @@ -0,0 +1,23 @@ +package com.canvas.web.modules.logging.service.dto; + + +import lombok.Data; + +import java.io.Serializable; +import java.sql.Timestamp; + +@Data +public class LogSmallDTO implements Serializable { + + private String decription; + + private String requestIp; + + private Long time; + + private String address; + + private String browser; + + private Timestamp createTime; +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/impl/LogServiceImpl.java b/system/src/main/java/com/canvas/web/modules/logging/service/impl/LogServiceImpl.java new file mode 100644 index 0000000..6d5f3b5 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/impl/LogServiceImpl.java @@ -0,0 +1,135 @@ +package com.canvas.web.modules.logging.service.impl; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.canvas.web.modules.logging.domain.Log; +import com.canvas.web.modules.logging.repository.LogRepository; +import com.canvas.web.modules.logging.service.LogService; +import com.canvas.web.modules.logging.service.dto.LogQueryCriteria; +import com.canvas.web.modules.logging.service.mapstruct.LogErrorMapper; +import com.canvas.web.modules.logging.service.mapstruct.LogSmallMapper; +import com.canvas.web.utils.*; +import lombok.RequiredArgsConstructor; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +@Service +@RequiredArgsConstructor +public class LogServiceImpl implements LogService { + + private final LogRepository logRepository; + private final LogErrorMapper logErrorMapper; + private final LogSmallMapper logSmallMapper; + + + + @Override + public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + String status = "ERROR"; + if (status.equals(criteria.getLogType())) { + return PageUtil.toPage(page.map(logErrorMapper::toDto)); + } + return page; + } + + + @Override + public List queryAll(LogQueryCriteria criteria) { + return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))); + } + + @Override + public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + return PageUtil.toPage(page.map(logSmallMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) { + if (log == null) { + throw new IllegalArgumentException("Log 不能为 null!"); + } + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + com.canvas.web.modules.logging.annotation.Log aopLog = method.getAnnotation( com.canvas.web.modules.logging.annotation.Log.class); + + // 方法路径 + String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; + + // 描述 + log.setDescription(aopLog.value()); + + log.setRequestIp(ip); + log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); + log.setMethod(methodName); + log.setUsername(username); + log.setParams(getParameter(method, joinPoint.getArgs())); + log.setBrowser(browser); + logRepository.save(log); + } + + /** + * 根据方法和传入的参数获取请求参数 + */ + private String getParameter(Method method, Object[] args) { + List argList = new ArrayList<>(); + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + //将RequestBody注解修饰的参数作为请求参数 + RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); + if (requestBody != null) { + argList.add(args[i]); + } + //将RequestParam注解修饰的参数作为请求参数 + RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); + if (requestParam != null) { + Map map = new HashMap<>(4); + String key = parameters[i].getName(); + if (!StringUtils.isEmpty(requestParam.value())) { + key = requestParam.value(); + } + map.put(key, args[i]); + argList.add(map); + } + } + if (argList.isEmpty()) { + return ""; + } + return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); + } + + @Override + public Object findByErrDetail(Long id) { + Log log = logRepository.findById(id).orElseGet(Log::new); + ValidationUtil.isNull(log.getId(), "Log", "id", id); + byte[] details = log.getExceptionDetail(); + return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); + } + + + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByError() { + logRepository.deleteByLogType("ERROR"); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delAllByInfo() { + logRepository.deleteByLogType("INFO"); + } +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogErrorMapper.java b/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogErrorMapper.java new file mode 100644 index 0000000..70b2648 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogErrorMapper.java @@ -0,0 +1,11 @@ +package com.canvas.web.modules.logging.service.mapstruct; + +import com.canvas.web.base.BaseMapper; +import com.canvas.web.modules.logging.domain.Log; +import com.canvas.web.modules.logging.service.dto.LogErrorDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogErrorMapper extends BaseMapper { +} diff --git a/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogSmallMapper.java b/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogSmallMapper.java new file mode 100644 index 0000000..da11105 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/logging/service/mapstruct/LogSmallMapper.java @@ -0,0 +1,12 @@ +package com.canvas.web.modules.logging.service.mapstruct; + +import com.canvas.web.base.BaseMapper; +import com.canvas.web.modules.logging.domain.Log; +import com.canvas.web.modules.logging.service.dto.LogSmallDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + + +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogSmallMapper extends BaseMapper { +} diff --git a/system/src/main/java/com/canvas/web/modules/system/controller/RoleController.java b/system/src/main/java/com/canvas/web/modules/system/controller/RoleController.java index 21fec27..29fc80a 100644 --- a/system/src/main/java/com/canvas/web/modules/system/controller/RoleController.java +++ b/system/src/main/java/com/canvas/web/modules/system/controller/RoleController.java @@ -4,6 +4,7 @@ import com.canvas.web.annotation.rest.AnonymousGetMapping; import com.canvas.web.annotation.rest.AnonymousPostMapping; import com.canvas.web.enums.ResponseEnum; import com.canvas.web.exception.BaseException; +import com.canvas.web.modules.system.domain.Role; import com.canvas.web.modules.system.service.RoleService; import com.canvas.web.modules.system.service.dto.RoleDto; import com.canvas.web.modules.system.service.dto.RoleQueryCriteria; @@ -15,7 +16,9 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; +import org.springframework.util.ObjectUtils; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -39,6 +42,7 @@ public class RoleController { @ApiOperation("新增角色") @AnonymousPostMapping("/create") public Response create(@Validated @RequestBody RoleDto roleDto){ + Long id = SecurityUtils.getCurrentOrgId(); if (roleDto.getId() !=null){ throw new BaseException("A new cannot already have an ID", ResponseEnum.ROLE_ADD_ERROR_EXIST_ID.getMessage()); } @@ -53,11 +57,29 @@ public class RoleController { @ApiOperation("查询角色") @AnonymousGetMapping("/list") public Response queryAllRole(RoleQueryCriteria criteria, Pageable pageable){ - return new Response<>(roleService.queryAll(criteria,pageable)); + //获取当前登录组织机构id + Long id = SecurityUtils.getCurrentOrgId(); + if (id!=1L){ + criteria.getOrgIds().add(id); + //如果查询条件不为空 + if (!ObjectUtils.isEmpty(criteria.getBlurry())) { + return Response.success(roleService.queryAll(criteria,pageable)); + } + return Response.success(roleService.queryAll(criteria, pageable)); + } + return Response.success(roleService.queryAll(criteria,pageable)); + } + + @ApiOperation("修改角色") + @PutMapping("edit") + public Response updateRole(@Validated(Role.Update.class) @RequestBody RoleDto role){ + roleService.update(role); + return Response.success("修改成功"); } + //TODO:暂时不需要判断用户等级 private int getLevels(Integer level){ List levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); int min = Collections.min(levels); diff --git a/system/src/main/java/com/canvas/web/modules/system/service/dto/RoleQueryCriteria.java b/system/src/main/java/com/canvas/web/modules/system/service/dto/RoleQueryCriteria.java index 4e151ee..6ee2656 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/dto/RoleQueryCriteria.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/dto/RoleQueryCriteria.java @@ -4,7 +4,9 @@ import com.canvas.web.annotation.Query; import lombok.Data; import java.sql.Timestamp; +import java.util.HashSet; import java.util.List; +import java.util.Set; @Data @@ -14,4 +16,7 @@ public class RoleQueryCriteria { @Query(type = Query.Type.BETWEEN) private List createTime; + + @Query(propName = "id", type = Query.Type.IN, joinName = "org") + private Set OrgIds = new HashSet<>(); } diff --git a/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java b/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java index c37f986..96ddc9a 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java @@ -62,6 +62,7 @@ public class UserServiceImpl implements UserService { } @Override + @Transactional(rollbackFor = Exception.class) public void update(User resources) throws Exception { User user = userRepository.findById(resources.getId()).orElseGet(User::new); ValidationUtil.isNull(user.getId(), "User", "id", resources.getId()); @@ -74,8 +75,8 @@ public class UserServiceImpl implements UserService { throw new BaseException("phone", resources.getPhone()); } //如果用户的角色改变 - if (!resources.getRoles().equals(user.getRoles())){ - redisUtils.del(CacheKey.DATA_USER +resources.getId()); + if (!resources.getRoles().equals(user.getRoles())) { + redisUtils.del(CacheKey.DATA_USER + resources.getId()); redisUtils.del(CacheKey.MENU_USER + resources.getId()); redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); } @@ -88,13 +89,20 @@ public class UserServiceImpl implements UserService { user.setNickName(resources.getNickName()); user.setRoles(resources.getRoles()); user.setOrg(resources.getOrg()); + user.setEnabled(resources.getEnabled()); userRepository.save(user); //清除缓存 - delCaches(user.getId(),user.getUsername()); + delCaches(user.getId(), user.getUsername()); } @Override + @Transactional(rollbackFor = Exception.class) public void delete(Set ids) { + for (Long id : ids) { + UserDto userDto = findById(id); + delCaches(userDto.getId(), userDto.getUsername()); + } + userRepository.deleteAllByIdIn(ids); }