diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/ServiceAspect.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/ServiceAspect.java index 679a221..d9a5aa1 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/ServiceAspect.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/ServiceAspect.java @@ -1,11 +1,13 @@ package com.electromagnetic.industry.software.manage.aop; import cn.hutool.json.JSONUtil; +import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; +import com.electromagnetic.industry.software.common.util.UserThreadLocal; import lombok.extern.slf4j.Slf4j; -import org.apache.catalina.connector.ResponseFacade; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; @@ -13,8 +15,8 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @Aspect @Component @@ -29,30 +31,34 @@ public class ServiceAspect { String methodInfo = jp.getTarget().getClass().getSimpleName() + "." + jp.getSignature().getName(); Object[] args = jp.getArgs(); + String[] argNames = ((MethodSignature)jp.getSignature()).getParameterNames(); String paramInfo = ""; if (args != null && args.length > 0) { - if (args[0] != null && args[0].getClass() != ResponseFacade.class) { - try { - List list = new ArrayList<>(); - for (Object obj : jp.getArgs()) { - - if (obj instanceof ServletResponse) { - log.info("参数中有response"); - } else if (obj instanceof ServletRequest) { - log.info("参数中有request"); - } else if (obj instanceof MultipartFile) { - //文件不输出 - MultipartFile obj1 = (MultipartFile) obj; - log.info("参数中文件;文件名:{},文件大小:{}", obj1.getName(), obj1.getSize()); - break; - } else { - list.add(obj); - } + Map map = new HashMap<>(); + try { + for (int i = 0; i < args.length; i++) { + String name = argNames[i]; + Object value = args[i]; + if (value instanceof ServletRequest) { + log.info("参数中有request"); + map.put(name, "request"); + } else if (value instanceof ServletResponse) { + log.info("参数中有response"); + map.put(name, "response"); + } else if (value instanceof MultipartFile) { + MultipartFile file = (MultipartFile) value; + Map pars = new HashMap<>(); + pars.put("fileName", file.getOriginalFilename()); + pars.put("fileSize", file.getSize()); + map.put("file", pars); + } else { + map.put(name, value); } - paramInfo = JSONUtil.toJsonStr(list); - } catch (Exception e) { - log.warn("切面异常--->{}", e.getMessage()); } + } catch (Exception e) { + log.warn("切面异常--->{}", e.getMessage(), e); + } finally { + paramInfo = JSONUtil.toJsonStr(map); } } log.info("请求接口开始:{},参数:{}", methodInfo, paramInfo); @@ -63,6 +69,8 @@ public class ServiceAspect { if (rvt instanceof ResponseEntity) { return rvt; } + UserThreadLocal.setRes((ElectromagneticResult)rvt); + UserThreadLocal.setReqArgs(paramInfo); String returnInfo = JSONUtil.toJsonStr(rvt); log.info("请求接口结束:{},返回参数:{},接口耗时:{}", methodInfo, returnInfo, (System.currentTimeMillis() - startTime) + "毫秒"); stopwatch.stop(); diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/config/LoginInterceptor.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/config/LoginInterceptor.java index a65dbb0..03d67f0 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/config/LoginInterceptor.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/config/LoginInterceptor.java @@ -1,16 +1,24 @@ package com.electromagnetic.industry.software.manage.config; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.SystemClock; +import com.electromagnetic.industry.software.common.annotations.UserOperation; import com.electromagnetic.industry.software.common.cons.UserConstants; import com.electromagnetic.industry.software.common.enums.AdminTypeEnum; import com.electromagnetic.industry.software.common.pojo.UserLoginInfo; +import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; +import com.electromagnetic.industry.software.common.util.IdWorker; import com.electromagnetic.industry.software.common.util.TokenUtil; import com.electromagnetic.industry.software.common.util.UserThreadLocal; import com.electromagnetic.industry.software.manage.mapper.TokenMapper; +import com.electromagnetic.industry.software.manage.mapper.UserAccessLogMapper; +import com.electromagnetic.industry.software.manage.mapper.UserMapper; import com.electromagnetic.industry.software.manage.pojo.models.Token; +import com.electromagnetic.industry.software.manage.pojo.models.UserAccessLog; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @@ -26,8 +34,12 @@ public class LoginInterceptor implements HandlerInterceptor { @Resource private TokenMapper tokenMapper; + @Resource + private UserAccessLogMapper userAccessLogMapper; + @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + request.getSession().setAttribute("accessStartTime", System.currentTimeMillis()); // 首先校验token boolean isTokenValid = checkToken(request, response); if (!isTokenValid) { @@ -86,6 +98,31 @@ public class LoginInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + long accessStartTime = (long)request.getSession().getAttribute("accessStartTime"); + ElectromagneticResult result = UserThreadLocal.getResult(); + String reqArgs = UserThreadLocal.getReqArgs(); + long accessEndTime = System.currentTimeMillis(); + UserOperation userOperation = ((HandlerMethod) handler).getMethod().getAnnotation(UserOperation.class); + UserAccessLog userAccessLog = UserAccessLog.builder() + .id(IdWorker.getSnowFlakeIdString()) + .userId(UserThreadLocal.getUserId()) + .accessStartTime(DateUtil.date(accessStartTime)) + .accessEndTime(DateUtil.date(accessEndTime)) + .accessDuration(accessEndTime - accessStartTime) + .action(userOperation.value()) + .requestUrl(request.getRequestURL().toString()) + .reqArgs(reqArgs) + .remoteAddr(request.getRemoteAddr()) + .accessSuccess(true) + .createTime(new Date()) + .build(); + if (!result.getSuccess()) { + userAccessLog.setAccessSuccess(false); + userAccessLog.setFailureReason(result.getErrorMessage()); + } + // TODO 如果是下载的文件,那么返回的是ResponseEntity而不是ElectromagneticResult + userAccessLogMapper.insert(userAccessLog); UserThreadLocal.remove(); } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java index 8613023..c9d4828 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java @@ -132,4 +132,10 @@ public class EdFileInfoController { public ElectromagneticResult queryChildFolder(@RequestParam String parentId) { return edFileInfoService.queryChildFolder(parentId); } + + @RequiredPermission(value = FilePermission.VIEW) + @RequestMapping(value = "preview", method = RequestMethod.GET) + public ResponseEntity preview(@RequestParam String id, HttpServletResponse response) { + return edFileInfoService.preview(id, response); + } } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/mapper/UserAccessLogMapper.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/mapper/UserAccessLogMapper.java new file mode 100644 index 0000000..1a6fcdc --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/mapper/UserAccessLogMapper.java @@ -0,0 +1,9 @@ +package com.electromagnetic.industry.software.manage.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.electromagnetic.industry.software.manage.pojo.models.UserAccessLog; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface UserAccessLogMapper extends BaseMapper { +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/UserAccessLog.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/UserAccessLog.java new file mode 100644 index 0000000..53f0698 --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/UserAccessLog.java @@ -0,0 +1,37 @@ +package com.electromagnetic.industry.software.manage.pojo.models; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +@Data +@Builder +@TableName("user_access_log") +public class UserAccessLog { + + private String id; + + private String userId; + + private Date accessStartTime; + + private Date accessEndTime; + + private Long accessDuration; + + private String action; + + private String requestUrl; + + private String reqArgs; + + private String remoteAddr; + + private Boolean accessSuccess; + + private String failureReason; + + private Date createTime; +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java index e92d942..02f8001 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java @@ -164,4 +164,11 @@ public interface EdFileInfoService { * @return */ ElectromagneticResult queryChildFolder(String parentId); + + /** + * 文件预览 + * @param id + * @param response + */ + ResponseEntity preview(String id, HttpServletResponse response); } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java index 16b1ca0..b87faed 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java @@ -75,12 +75,14 @@ public class EdFileInfoServiceImpl extends ServiceImpl preview(String id, HttpServletResponse response) { + try { + EdFileInfo fileInfo = this.baseMapper.selectById(id); + Assert.isTrue(Objects.nonNull(fileInfo), "文件不存在"); + String fileSysPath = commonService.getFileSysPath(fileInfo.getFilePath()); + EleCommonUtil.decryptFile(fileSysPath, SecureUtil.aes(FILE_SEC_PASSWD.getBytes())); + if (Arrays.asList("doc", "docx").contains(fileInfo.getFileType())) { + String pdfTmpPath = tmpDir + File.separator + fileInfo.getFileName() + "_" + IdUtil.fastSimpleUUID() + ".pdf"; + OfficeFileUtil.doc2pdf(fileSysPath, pdfTmpPath); + fileSysPath = pdfTmpPath; + } + FileSystemResource fileSystemResource = new FileSystemResource(fileSysPath); + String fileName = fileSystemResource.getFilename(); + HttpHeaders headers = new HttpHeaders(); + headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); + headers.add("Pragma", "no-cache"); + headers.add("Expires", "0"); + fileName = Base64.encode(fileName.substring(0, fileName.lastIndexOf("."))); + response.setHeader("content-disposition", "attachment;filename=" + fileName); + // 构建响应实体(可以返回{},错误信息--->{}", id,e.getMessage()); + log.error(info, e); + throw new BizException(info); + } + } + } diff --git a/electrmangnetic/src/main/resources/application.properties b/electrmangnetic/src/main/resources/application.properties index e364943..625816f 100644 --- a/electrmangnetic/src/main/resources/application.properties +++ b/electrmangnetic/src/main/resources/application.properties @@ -17,10 +17,12 @@ server.port=12396 data.windows.path=D:/tmp/szsd/data/eleData/dev/project/ data.upload.windows.tmp.path=D:/tmp/szsd/data/eleData/dev/upload/ data.download.windows.tmp.path=D:/tmp/szsd/data/eleData/dev/download/ +data.windows.tmp.path=D:/szsd/data/eleData/dev/tmp data.linux.path=/szsd/data/eleData/dev/project/ data.upload.linux.tmp.path=/szsd/data/eleData/dev/upload/ data.download.linux.tmp.path=/szsd/data/eleData/dev/download/ +data.linux.tmp.path=/szsd/data/eleData/dev/tmp prj.folder.max.length=6 diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/UserOperation.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/UserOperation.java new file mode 100644 index 0000000..37a57d7 --- /dev/null +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/UserOperation.java @@ -0,0 +1,11 @@ +package com.electromagnetic.industry.software.common.annotations; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.PARAMETER}) +public @interface UserOperation { + + String value() default ""; +} diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/pojo/UserLoginInfo.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/pojo/UserLoginInfo.java index 456b11f..7520402 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/pojo/UserLoginInfo.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/pojo/UserLoginInfo.java @@ -1,5 +1,6 @@ package com.electromagnetic.industry.software.common.pojo; +import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import lombok.Data; @Data @@ -34,4 +35,14 @@ public class UserLoginInfo { * 管理员类型 */ private String adminType; + + /** + * 返回值 + */ + private ElectromagneticResult result; + + /** + * 访问请求的参数 + */ + private String reqArgs; } diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java index db23f7c..59c9c7d 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java @@ -57,13 +57,25 @@ public final class EleCommonUtil { return now.format(formatter); } + public static void decryptFile(String filePath, AES aes) { + handleFile(filePath, aes, false); + } + public static void encryptFile(String filePath, AES aes) { + handleFile(filePath, aes, true); + } + + private static void handleFile(String filePath, AES aes, boolean encrypt) { String tmpPath = filePath + ".tmp"; try ( InputStream inputStream = Files.newInputStream(Paths.get(filePath)); OutputStream outputStream = Files.newOutputStream(Paths.get(tmpPath)); ) { - aes.encrypt(inputStream, outputStream, true); + if (encrypt) { + aes.encrypt(inputStream, outputStream, true); + } else { + aes.decrypt(inputStream, outputStream, true); + } } catch (Exception e) { String info = "文件加密失败"; log.error(info, e); diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/UserThreadLocal.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/UserThreadLocal.java index 10243be..09e4cf3 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/UserThreadLocal.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/UserThreadLocal.java @@ -2,12 +2,13 @@ package com.electromagnetic.industry.software.common.util; import com.electromagnetic.industry.software.common.pojo.UserLoginInfo; +import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; public class UserThreadLocal { /** * 存储用户信息 */ - private static ThreadLocal userThread = new ThreadLocal<>(); + private static final ThreadLocal userThread = new ThreadLocal<>(); public static void set(UserLoginInfo userLoginInfo) { userThread.set(userLoginInfo); @@ -32,4 +33,21 @@ public class UserThreadLocal { public static void remove() { userThread.remove(); } + + public static void setRes(ElectromagneticResult result) { + userThread.get().setResult(result); + } + + public static ElectromagneticResult getResult() { + return userThread.get().getResult(); + } + + public static void setReqArgs(String args) { + userThread.get().setReqArgs(args); + } + + public static String getReqArgs() { + return userThread.get().getReqArgs(); + } + } \ No newline at end of file