越权系统框架整改

This commit is contained in:
cwchen 2025-09-09 14:05:48 +08:00
parent d3dc26b1ea
commit 24a1021348
19 changed files with 870 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import com.bonus.common.annotation.RequiresPermissions;
import com.bonus.common.annotation.SysLog;
import com.bonus.common.enums.OperaType;
import com.bonus.common.utils.encryption.Sm4Utils;
@ -60,7 +61,8 @@ public class SysUserController extends BaseController
/**
* 获取用户列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
// @PreAuthorize("@ss.hasPermi('system:user:list')")
@RequiresPermissions("system:user:list")
@GetMapping("/list")
@SysLog(title = "用户管理", businessType = OperaType.QUERY, logType = 0, module = "系统管理->用户管理", details = "查询用户列表")
public TableDataInfo list(SysUser user)
@ -253,7 +255,8 @@ public class SysUserController extends BaseController
/**
* 获取部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
// @PreAuthorize("@ss.hasPermi('system:user:list')")
@RequiresPermissions("system:user:list")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept)
{

View File

@ -0,0 +1,20 @@
package com.bonus.common.annotation;
/**
* 权限注解的验证模式
*
* @author bonus
*
*/
public enum Logical
{
/**
* 必须具有所有的元素
*/
AND,
/**
* 只需具有其中一个元素
*/
OR
}

View File

@ -0,0 +1,18 @@
package com.bonus.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 登录认证只有登录之后才能进入该方法
*
* @author bonus
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequiresLogin
{
}

View File

@ -0,0 +1,35 @@
package com.bonus.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限认证必须具有指定权限才能进入该方法
*
* @author bonus
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequiresPermissions
{
/**
* 需要校验的权限码
*/
String[] value() default {};
/**
* 验证模式AND | OR默认AND
*/
Logical logical() default Logical.AND;
}

View File

@ -0,0 +1,25 @@
package com.bonus.common.context;
/**
* @className:PermissionContextHolder
* @author:cwchen
* @date:2025-09-09-10:43
* @version:1.0
* @description:权限上下文持有类
*/
public class PermissionContextHolder {
private static final ThreadLocal<String> PERMISSION_CONTEXT = new ThreadLocal<>();
public static void setPermission(String permission) {
PERMISSION_CONTEXT.set(permission);
}
public static String getPermission() {
return PERMISSION_CONTEXT.get();
}
public static void clear() {
PERMISSION_CONTEXT.remove();
}
}

View File

@ -0,0 +1,16 @@
package com.bonus.common.exception;
/**
* 未能通过的登录认证异常
*
* @author bonus
*/
public class NotLoginException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public NotLoginException(String message)
{
super(message);
}
}

View File

@ -0,0 +1,23 @@
package com.bonus.common.exception;
import org.apache.commons.lang3.StringUtils;
/**
* 未能通过的权限认证异常
*
* @author bonus
*/
public class NotPermissionException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public NotPermissionException(String permission)
{
super(permission);
}
public NotPermissionException(String[] permissions)
{
super(StringUtils.join(permissions, ","));
}
}

View File

@ -0,0 +1,85 @@
package com.bonus.framework.aspectj;
import com.bonus.common.annotation.RequiresPermissions;
import com.bonus.framework.auth.AuthLogic;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 基于 Spring Aop 的注解鉴权
*
* @author kong
*/
@Aspect
@Component
public class PreAuthorizeAspect
{
@Autowired
AuthLogic authLogic;
/**
* 构建
*/
public PreAuthorizeAspect()
{
}
/**
* 定义AOP签名 (切入所有使用鉴权注解的方法)
*/
public static final String POINTCUT_SIGN = "@annotation(com.bonus.common.annotation.RequiresPermissions)";
/**
* 声明AOP签名
*/
@Pointcut(POINTCUT_SIGN)
public void pointcut()
{
}
/**
* 环绕切入
*
* @param joinPoint 切面对象
* @return 底层方法执行后的返回值
* @throws Throwable 底层方法抛出的异常
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable
{
// 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
checkMethodAnnotation(signature.getMethod(),joinPoint);
try
{
// 执行原有逻辑
Object obj = joinPoint.proceed();
return obj;
}
catch (Throwable e)
{
throw e;
}
}
/**
* 对一个Method对象进行注解检查
*/
public void checkMethodAnnotation(Method method,ProceedingJoinPoint joinPoint)
{
// 校验 @RequiresPermissions 注解
RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
if (requiresPermissions != null)
{
authLogic.checkPermi(requiresPermissions,joinPoint);
}
}
}

View File

@ -0,0 +1,271 @@
package com.bonus.framework.auth;
import cn.hutool.json.JSONObject;
import com.bonus.common.annotation.Logical;
import com.bonus.common.annotation.RequiresLogin;
import com.bonus.common.annotation.RequiresPermissions;
import com.bonus.common.context.PermissionContextHolder;
import com.bonus.common.core.domain.model.LoginUser;
import com.bonus.common.exception.NotLoginException;
import com.bonus.common.utils.DateUtils;
import com.bonus.common.utils.SecurityUtils;
import com.bonus.common.utils.StringUtils;
import com.bonus.common.utils.ip.IpUtils;
import com.bonus.framework.manager.AsyncManager;
import com.bonus.framework.manager.factory.AsyncFactory;
import com.bonus.framework.web.service.TokenService;
import com.bonus.system.domain.SysLogsVo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
import org.springframework.util.PatternMatchUtils;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
/**
* @className:AuthLogic
* @author:cwchen
* @date:2025-09-08-17:54
* @version:1.0
* @description:鉴权实现类
*/
@Component
public class AuthLogic {
@Autowired
private TokenService tokenService;
/**
* 所有权限标识
*/
private static final String ALL_PERMISSION = "*:*:*";
/**
* 管理员角色权限标识
*/
private static final String SUPER_ADMIN = "admin";
/**
* 管理员角色权限标识
*/
private static final String COMPANY_ADMIN = "company_admin";
/**
* 检验用户是否已经登录如未登录则抛出异常
*/
public void checkLogin() {
getLoginUser();
}
/**
* 获取当前用户缓存信息, 如果未登录则抛出异常
*
* @return 用户缓存信息
*/
public LoginUser getLoginUser() {
String token = tokenService.getToken();
if (token == null) {
throw new NotLoginException("未提供token");
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
throw new NotLoginException("无效的token");
}
return loginUser;
}
/**
* 获取当前用户缓存信息, 如果未登录则抛出异常
*
* @param token 前端传递的认证信息
* @return 用户缓存信息
*/
public LoginUser getLoginUser(String token) {
return tokenService.getLoginUser(token);
}
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission) {
return hasPermi(getPermiList(), permission);
}
/**
* 根据注解(@RequiresPermissions)鉴权, 如果验证未通过则抛出异常: NotPermissionException
*
* @param requiresPermissions 注解对象
*/
public void checkPermi(RequiresPermissions requiresPermissions, ProceedingJoinPoint joinPoint) {
// 获取请求参数
boolean needPermission = true;
Object[] args = joinPoint.getArgs();
for (Object obj : args) {
if (obj instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) obj;
if ("1".equals(jsonObject.getStr("skipPermission"))) {
needPermission = false;
break;
}
}
}
if (needPermission) {
// 使用自定义的PermissionContextHolder替代SecurityContextHolder
PermissionContextHolder.setPermission(StringUtils.join(requiresPermissions.value(), ","));
try {
if (requiresPermissions.logical() == Logical.AND) {
checkPermiAnd(requiresPermissions.value());
} else {
checkPermiOr(requiresPermissions.value());
}
} catch (AccessDeniedException e) {
// 记录越权日志异步处理不阻塞当前线程
addErrorLogsAsync(joinPoint, requiresPermissions, e.getMessage());
throw e;
} finally {
// 清理ThreadLocal防止内存泄漏
PermissionContextHolder.clear();
}
}
}
/**
* 异步记录越权日志不阻塞当前线程
*/
private void addErrorLogsAsync(ProceedingJoinPoint joinPoint, RequiresPermissions requiresPermissions, String errorMessage) {
try {
LoginUser loginUser = getLoginUser();
loginUser.setIpaddr(IpUtils.getIpAddr());
SysLogsVo vo = SysLogsVo.getExceedAuthorithSysLogsVo(loginUser, joinPoint);
// 假设LogsUtils.setRequestValue存在如果不存在需要处理
LogsUtils.setRequestValue(joinPoint, vo, null);
// 设置基础信息
vo.setParams(StringUtils.join(requiresPermissions.value(), ","));
vo.setOperTime(DateUtils.getTime());
vo.setTimes("0");
// 异步查询日志模块信息并记录日志
CompletableFuture.runAsync(() -> {
try {
SysLogsVo queryVo = new SysLogsVo();
queryVo.setParams(requiresPermissions.value()[0]);
// 异步查询日志模块信息
Future<Map<String, String>> mapFuture = AsyncManager.me().executeGetLogsModule(queryVo);
Map<String, String> result = mapFuture.get(); // 这里在异步线程中阻塞是可以的
// 设置查询结果
vo.setModel(result.get("module"));
vo.setTitle(result.get("title"));
vo.setOperateDetail(result.get("detail"));
vo.setOperType(result.get("bussType"));
vo.setResultData(result.get("resultData"));
// 记录日志
AsyncManager.me().execute(AsyncFactory.addSysOperLog(vo));
} catch (Exception e) {
System.err.println("越权日志记录失败: " + e.getMessage());
// 即使查询失败也记录基础日志信息
vo.setTitle("权限验证失败");
vo.setOperateDetail("查询操作模块信息失败");
AsyncManager.me().execute(AsyncFactory.addSysOperLog(vo));
}
});
} catch (Exception e) {
System.err.println("越权日志记录初始化失败: " + e.getMessage());
}
}
/**
* 验证用户是否含有指定权限必须全部拥有
*
* @param permissions 权限列表
*/
public void checkPermiAnd(String... permissions) {
Set<String> permissionList = getPermiList();
for (String permission : permissions) {
System.err.println(hasPermi(permissionList, permission));
if (!hasPermi(permissionList, permission)) {
// throw new NotPermissionException(permission);
throw new AccessDeniedException(permission+":越权访问");
}
}
}
/**
* 验证用户是否含有指定权限只需包含其中一个
*
* @param permissions 权限码数组
*/
public void checkPermiOr(String... permissions) {
Set<String> permissionList = getPermiList();
for (String permission : permissions) {
if (hasPermi(permissionList, permission)) {
return;
}
}
if (permissions.length > 0) {
// throw new NotPermissionException(permissions);
throw new AccessDeniedException("越权访问");
}
}
/**
* 根据注解(@RequiresLogin)鉴权
*
* @param at 注解对象
*/
public void checkByAnnotation(RequiresLogin at) {
this.checkLogin();
}
/**
* 根据注解(@RequiresPermissions)鉴权
*
* @param at 注解对象
*/
public void checkByAnnotation(RequiresPermissions at) {
String[] permissionArray = at.value();
if (at.logical() == Logical.AND) {
this.checkPermiAnd(permissionArray);
} else {
this.checkPermiOr(permissionArray);
}
}
/**
* 获取当前账号的权限列表
*
* @return 权限列表
*/
public Set<String> getPermiList() {
try {
LoginUser loginUser = getLoginUser();
return loginUser.getPermissions();
} catch (Exception e) {
return new HashSet<>();
}
}
/**
* 判断是否包含权限
*
* @param authorities 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(Collection<String> authorities, String permission) {
return authorities.stream().filter(StringUtils::hasText)
.anyMatch(x -> ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission));
}
}

View File

@ -0,0 +1,114 @@
package com.bonus.framework.auth;
import com.alibaba.fastjson2.JSON;
import com.bonus.common.utils.ServletUtils;
import com.bonus.common.utils.StringUtils;
import com.bonus.system.domain.SysLogsVo;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.http.HttpMethod;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;
/**
* @author bonus
*/
public class LogsUtils {
/**
* 获取请求的参数放到log中
*
* @param operLog 操作日志
* @throws Exception 异常
*/
public static void setRequestValue(ProceedingJoinPoint joinPoint, SysLogsVo operLog, String[] excludeParamNames) throws Exception {
String requestMethod = operLog.getMethod();
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
boolean bResult = HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod);
if (StringUtils.isEmpty(paramsMap) && bResult)
{
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
operLog.setParams(StringUtils.substring(params, 0, 2000));
}
else {
operLog.setParams(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
}
}
/**
* 参数拼装
*/
private static String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
{
String params = "";
if (paramsArray != null && paramsArray.length > 0)
{
for (Object o : paramsArray)
{
if (StringUtils.isNotNull(o) && !isFilterObject(o))
{
try
{
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
params += jsonObj.toString() + " ";
}
catch (Exception e)
{
}
}
}
}
return params.trim();
}
/** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/**
* 忽略敏感属性
*/
public static PropertyPreExcludeFilter2 excludePropertyPreFilter(String[] excludeParamNames)
{
return new PropertyPreExcludeFilter2().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
}
/**
* 判断是否需要过滤的对象
*
* @param o 对象信息
* @return 如果是需要过滤的对象则返回true否则返回false
*/
@SuppressWarnings("rawtypes")
public static boolean isFilterObject(final Object o)
{
Class<?> clazz = o.getClass();
if (clazz.isArray())
{
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
}
else if (Collection.class.isAssignableFrom(clazz))
{
Collection collection = (Collection) o;
for (Object value : collection)
{
return value instanceof MultipartFile;
}
}
else if (Map.class.isAssignableFrom(clazz))
{
Map map = (Map) o;
for (Object value : map.entrySet())
{
Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
}

View File

@ -0,0 +1,24 @@
package com.bonus.framework.auth;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
/**
* 排除JSON敏感属性
*
* @author bonus
*/
public class PropertyPreExcludeFilter2 extends SimplePropertyPreFilter
{
public PropertyPreExcludeFilter2()
{
}
public PropertyPreExcludeFilter2 addExcludes(String... filters)
{
for (int i = 0; i < filters.length; i++)
{
this.getExcludes().add(filters[i]);
}
return this;
}
}

View File

@ -1,10 +1,13 @@
package com.bonus.framework.manager;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import com.bonus.common.utils.Threads;
import com.bonus.common.utils.spring.SpringUtils;
import com.bonus.system.domain.SysLogsVo;
import com.bonus.system.service.ISysOperLogService;
/**
* 异步任务管理器
@ -45,6 +48,48 @@ public class AsyncManager
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 执行带返回值的任务
*
* @param task 带返回值的任务
* @param <T> 返回值类型
* @return Future对象用于获取执行结果
*/
public <T> Future<T> execute(Callable<T> task)
{
return executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 执行FutureTask任务
*
* @param futureTask FutureTask任务
* @param <T> 返回值类型
* @return Future对象用于获取执行结果
*/
public <T> Future<T> execute(FutureTask<T> futureTask)
{
executor.schedule(futureTask, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
return futureTask;
}
/**
* 执行查询日志模块的异步任务
*
* @param sysLogsVo 操作日志信息
* @return Future对象用于获取查询结果
*/
public Future<Map<String, String>> executeGetLogsModule(final SysLogsVo sysLogsVo)
{
Callable<Map<String, String>> callable = new Callable<Map<String, String>>() {
@Override
public Map<String, String> call() throws Exception {
return SpringUtils.getBean(ISysOperLogService.class).getLogsModule(sysLogsVo);
}
};
return execute(callable);
}
/**
* 停止任务线程池
*/

View File

@ -1,6 +1,9 @@
package com.bonus.framework.manager.factory;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import com.bonus.system.domain.SysLogsVo;
import org.slf4j.Logger;
@ -121,4 +124,23 @@ public class AsyncFactory
}
};
}
/**
* 查询操作的日志模块
*
* @param sysLogsVo 操作日志信息
* @return 任务task
*/
public static FutureTask<Map<String,String>> getLogsModule(final SysLogsVo sysLogsVo)
{
Callable<Map<String,String>> callable = new Callable<Map<String,String>>() {
@Override
public Map<String,String> call() throws Exception {
return SpringUtils.getBean(ISysOperLogService.class).getLogsModule(sysLogsVo);
}
};
return new FutureTask<>(callable);
}
}

View File

@ -236,4 +236,31 @@ public class TokenService
{
return CacheConstants.LOGIN_TOKEN_KEY + uuid;
}
/**
* 获取请求token
*/
public String getToken()
{
return getToken(ServletUtils.getRequest());
}
public LoginUser getLoginUser(String token){
if (StringUtils.isNotEmpty(token)){
try
{
Claims claims = parseToken(token);
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid);
LoginUser user = redisCache.getCacheObject(userKey);
return user;
}
catch (Exception e)
{
log.error("获取用户信息异常'{}'", e.getMessage());
}
}
return null;
}
}

View File

@ -0,0 +1,24 @@
package com.bonus.system.domain;
import lombok.Data;
/**
* 日志菜单头
* @author weiweiw
*/
@Data
public class SysLogsMenuHead {
public String menuName;
private String menuType;
public String menuName2;
public String menuName3;
public String menuName4;
}

View File

@ -2,6 +2,7 @@ package com.bonus.system.mapper;
import java.util.List;
import com.bonus.system.domain.SysLogsMenuHead;
import com.bonus.system.domain.SysLogsVo;
import com.bonus.system.domain.SysOperLog;
@ -65,4 +66,13 @@ public interface SysOperLogMapper
* @date 2025/9/5 13:41
*/
SysLogsVo getModule(String operUri);
/**
* 查询 异常日志路径
* @param sysLogsVo
* @return List<SysLogsMenuHead>
* @author cwchen
* @date 2025/9/9 9:55
*/
List<SysLogsMenuHead> getLogsErrorModule(SysLogsVo sysLogsVo);
}

View File

@ -1,6 +1,7 @@
package com.bonus.system.service;
import java.util.List;
import java.util.Map;
import com.bonus.system.domain.SysLogsVo;
import com.bonus.system.domain.SysOperLog;
@ -56,4 +57,13 @@ public interface ISysOperLogService
* @date 2025/9/5 13:14
*/
void addSysOperLog(SysLogsVo sysLogsVo);
/**
* 查询操作模块
* @param sysLogsVo
* @return Map<String,String>
* @author cwchen
* @date 2025/9/9 9:51
*/
Map<String, String> getLogsModule(SysLogsVo sysLogsVo);
}

View File

@ -1,10 +1,16 @@
package com.bonus.system.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.bonus.common.utils.global.SystemGlobal;
import com.alibaba.fastjson2.JSON;
import com.bonus.common.enums.OperaType;
import com.bonus.system.domain.SysLogsMenuHead;
import com.bonus.system.domain.SysLogsVo;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -26,6 +32,8 @@ public class SysOperLogServiceImpl implements ISysOperLogService
@Autowired
private SysOperLogMapper operLogMapper;
public static final String MENU_TYPE_FILE = "F";
/**
* 新增操作日志
*
@ -103,4 +111,77 @@ public class SysOperLogServiceImpl implements ISysOperLogService
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
@Override
public Map<String, String> getLogsModule(SysLogsVo sysLogsVo) {
Map<String, String> maps= Maps.newHashMap();
Map result=Maps.newHashMap();
result.put("code","403");
result.put("data","");
result.put("msg","数据接口未授权");
try{
List<SysLogsMenuHead> list =operLogMapper.getLogsErrorModule(sysLogsVo);
if(CollectionUtils.isNotEmpty(list)){
SysLogsMenuHead vo=list.get(0);
StringBuffer sb=new StringBuffer();
String type=vo.getMenuType();
if(StringUtils.isNotEmpty(vo.getMenuName4())){
sb.append(vo.getMenuName4());
}
if(StringUtils.isNotEmpty(vo.getMenuName3())){
sbAppend(sb);
sb.append(vo.getMenuName3());
}
if(StringUtils.isNotEmpty(vo.getMenuName2())){
sbAppend(sb);
sb.append(vo.getMenuName2());
}
if( MENU_TYPE_FILE .equals(type)){
if(vo.getMenuName().contains(OperaType.INSERT)){
maps.put("bussType",OperaType.INSERT);
}else if(vo.getMenuName().contains(OperaType.UPDATE)){
maps.put("bussType",OperaType.UPDATE);
}else if(vo.getMenuName().contains(OperaType.DELETE)){
maps.put("bussType",OperaType.DELETE);
}else if(vo.getMenuName().contains(OperaType.IMPORT)){
maps.put("bussType",OperaType.IMPORT);
}else if(vo.getMenuName().contains(OperaType.DOWNLOAD)){
maps.put("bussType",OperaType.DOWNLOAD);
}else if(vo.getMenuName().contains(OperaType.EXPORT)){
maps.put("bussType",OperaType.EXPORT);
}else if(vo.getMenuName().contains(OperaType.FLASH)){
maps.put("bussType",OperaType.FLASH);
}else if(vo.getMenuName().contains(OperaType.GRANT)){
maps.put("bussType",OperaType.GRANT);
} else {
maps.put("bussType",OperaType.OTHER);
}
maps.put("title",vo.getMenuName2());
}else{
maps.put("bussType",OperaType.QUERY);
sbAppend(sb);
sb.append(vo.getMenuName());
maps.put("title",vo.getMenuName());
}
maps.put("detail", "进行数据的"+maps.get("bussType"));
maps.put("module",sb.toString());
maps.put("resultData", JSON.toJSONString(result));
}
}catch (Exception e){
maps.put("resultData", JSON.toJSONString(result));
maps.put("title","智慧图档");
maps.put("module","智慧图档->数据接口");
maps.put("detail","进行数据访问");
maps.put("bussType", "未知");
log.error(e.toString(),e);
}
return maps;
}
public void sbAppend(StringBuffer sb){
if(StringUtils.isNotEmpty(sb.toString())){
sb.append("->");
}
}
}

View File

@ -106,8 +106,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where sm3.component=#{module}
limit 1
</select>
<!--查询 异常日志路径-->
<select id="getLogsErrorModule" resultType="com.bonus.system.domain.SysLogsMenuHead">
select sm.menu_name menuName,sm.menu_type menuType,sm2.menu_name menuName2,
sm3.menu_name menuName3,sm4.menu_name menuName4
FROM da_ky_sys_menu sm
left join da_ky_sys_menu sm2 on sm.parent_id=sm2.menu_id and sm2.visible=0
left join da_ky_sys_menu sm3 on sm2.parent_id=sm3.menu_id and sm3.visible=0
left join da_ky_sys_menu sm4 on sm3.parent_id=sm4.menu_id and sm4.visible=0
where sm.perms=#{params}
limit 1
</select>
<update id="cleanOperLog">
<update id="cleanOperLog">
truncate table da_ky_sys_oper_log
</update>