diff --git a/backend/src/main/java/io/dataease/commons/utils/IPUtils.java b/backend/src/main/java/io/dataease/commons/utils/IPUtils.java new file mode 100644 index 0000000000..8a9cc8088e --- /dev/null +++ b/backend/src/main/java/io/dataease/commons/utils/IPUtils.java @@ -0,0 +1,45 @@ +package io.dataease.commons.utils; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; + +public class IPUtils { + + private static final String HEAD_KEYS = "x-forwarded-for, Proxy-Client-IP, WL-Proxy-Client-IP"; + + private static final String UNKNOWN = "unknown"; + + private static final String LOCAL_IP_KEY = "0:0:0:0:0:0:0:1"; + private static final String LOCAL_IP_VAL = "127.0.0.1"; + + public static String get() { + + String ipStr = null; + boolean isProxy = false; + + HttpServletRequest request = null; + try { + request = ServletUtils.request(); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + return null; + } + String[] keyArr = HEAD_KEYS.split(","); + for (String key : keyArr) { + String header = request.getHeader(key.trim()); + if (StringUtils.isNotBlank(header) && !StringUtils.equalsIgnoreCase(UNKNOWN, header)) { + ipStr = header; + isProxy = true; + break; + } + } + + if (!isProxy) { + ipStr = request.getRemoteAddr(); + } + ipStr = Arrays.stream(ipStr.split(",")).filter(item -> StringUtils.isNotBlank(item) && !StringUtils.equalsIgnoreCase(UNKNOWN, item.trim())).findFirst().orElse(ipStr); + return StringUtils.equals(LOCAL_IP_KEY, ipStr) ? LOCAL_IP_VAL : ipStr; + } +} diff --git a/backend/src/main/java/io/dataease/dto/SysLogGridDTO.java b/backend/src/main/java/io/dataease/dto/SysLogGridDTO.java index 706d4a2762..66a644b2c4 100644 --- a/backend/src/main/java/io/dataease/dto/SysLogGridDTO.java +++ b/backend/src/main/java/io/dataease/dto/SysLogGridDTO.java @@ -22,4 +22,7 @@ public class SysLogGridDTO implements Serializable { @ApiModelProperty("操作时间") private Long time; + + @ApiModelProperty("IP地址") + private String ip; } diff --git a/backend/src/main/java/io/dataease/service/sys/log/LogService.java b/backend/src/main/java/io/dataease/service/sys/log/LogService.java index c668c57e39..0bdb492492 100644 --- a/backend/src/main/java/io/dataease/service/sys/log/LogService.java +++ b/backend/src/main/java/io/dataease/service/sys/log/LogService.java @@ -9,6 +9,7 @@ import io.dataease.commons.constants.ParamConstants; import io.dataease.commons.constants.SysLogConstants; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; +import io.dataease.commons.utils.IPUtils; import io.dataease.commons.utils.ServletUtils; import io.dataease.controller.sys.base.ConditionEntity; import io.dataease.controller.sys.request.KeyGridRequest; @@ -28,6 +29,7 @@ import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.*; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -308,6 +310,7 @@ public class LogService { sysLogGridDTO.setTime(vo.getTime()); sysLogGridDTO.setUser(vo.getNickName()); sysLogGridDTO.setDetail(logManager.detailInfo(vo)); + sysLogGridDTO.setIp(vo.getIp()); return sysLogGridDTO; } @@ -330,12 +333,14 @@ public class LogService { sysLogWithBLOBs.setLoginName(sysLogDTO.getSourceName()); sysLogWithBLOBs.setNickName(sysLogDTO.getSourceName()); } + sysLogWithBLOBs.setIp(IPUtils.get()); sysLogMapper.insert(sysLogWithBLOBs); } public void exportExcel(KeyGridRequest request) throws Exception { + request = logRetentionProxy(request); request = detailRequest(request); String keyWord = request.getKeyWord(); List ids = null; @@ -355,24 +360,25 @@ public class LogService { List details = lists.stream().map(item -> { String operateTypeName = SysLogConstants.operateTypeName(item.getOperateType()); String sourceTypeName = SysLogConstants.sourceTypeName(item.getSourceType()); - String[] row = new String[4]; + String[] row = new String[5]; row[0] = Translator.get(operateTypeName) + " " + Translator.get(sourceTypeName); row[1] = logManager.detailInfo(item); row[2] = item.getNickName(); - row[3] = DateUtil.formatDateTime(new Date(item.getTime())); + row[3] = item.getIp(); + row[4] = DateUtil.formatDateTime(new Date(item.getTime())); return row; }).collect(Collectors.toList()); - String[] headArr = {"操作类型", "详情", "用户", "时间"}; + String[] headArr = {"操作类型", "详情", "用户", "IP地址", "时间"}; details.add(0, headArr); - HSSFWorkbook wb = new HSSFWorkbook(); + XSSFWorkbook wb = new XSSFWorkbook(); //明细sheet - HSSFSheet detailsSheet = wb.createSheet("数据"); + XSSFSheet detailsSheet = wb.createSheet("数据"); //给单元格设置样式 - CellStyle cellStyle = wb.createCellStyle(); - Font font = wb.createFont(); + XSSFCellStyle cellStyle = wb.createCellStyle(); + XSSFFont font = wb.createFont(); //设置字体大小 font.setFontHeightInPoints((short) 12); //设置字体加粗 @@ -386,11 +392,11 @@ public class LogService { if (CollectionUtils.isNotEmpty(details)) { for (int i = 0; i < details.size(); i++) { - HSSFRow row = detailsSheet.createRow(i); + XSSFRow row = detailsSheet.createRow(i); String[] rowData = details.get(i); if (rowData != null) { for (int j = 0; j < rowData.length; j++) { - HSSFCell cell = row.createCell(j); + XSSFCell cell = row.createCell(j); cell.setCellValue(rowData[j]); if (i == 0) {// 头部 cell.setCellStyle(cellStyle); @@ -406,7 +412,7 @@ public class LogService { //文件名称 String fileName = "DataEase操作日志"; String encodeFileName = URLEncoder.encode(fileName, "UTF-8"); - response.setHeader("Content-disposition", "attachment;filename=" + encodeFileName + ".xls"); + response.setHeader("Content-disposition", "attachment;filename=" + encodeFileName + ".xlsx"); wb.write(outputStream); outputStream.flush(); outputStream.close(); diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 0a0fbedd08..37b9f1aed1 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -2605,7 +2605,8 @@ export default { time: 'Time', export: 'Export', confirm: 'Sure Export ?', - search_by_key: 'Search by key' + search_by_key: 'Search by key', + ip: 'IP' }, plugin_style: { border: 'Border' diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 06efa7fbd1..c08143f472 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -2606,7 +2606,8 @@ export default { time: '操作時間', export: '導出', confirm: '確定導出嗎?', - search_by_key: '搜索詳情' + search_by_key: '搜索詳情', + ip: 'IP地址' }, plugin_style: { border: '邊框' diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index acab15b99e..6465be6c4c 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -2606,7 +2606,8 @@ export default { time: '操作时间', export: '导出', confirm: '确定导出吗?', - search_by_key: '搜索详情' + search_by_key: '搜索详情', + ip: 'IP地址' }, plugin_style: { border: '边框' diff --git a/frontend/src/views/system/log/index.vue b/frontend/src/views/system/log/index.vue index 4067f27ee4..2a248bb83f 100644 --- a/frontend/src/views/system/log/index.vue +++ b/frontend/src/views/system/log/index.vue @@ -112,6 +112,12 @@ :label="$t('log.user')" width="100" /> +