You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

436 lines
19 KiB
Java

package com.engine.salary.elog.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.salary.elog.entity.dto.LoggerContext;
import com.engine.salary.elog.entity.dto.LoggerDetailContext;
import com.engine.salary.elog.enums.ElogConsts;
import com.engine.salary.elog.service.ILocalElogService;
import com.engine.salary.elog.util.ElogUtils;
import com.engine.salary.mapper.elog.LocalElogAopDaoMapper;
import com.engine.salary.elog.util.db.IdGenerator;
import com.engine.salary.elog.util.db.MapperProxyFactory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import weaver.conn.RecordSet;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* @ClassName: LocalElogService
* @Description
* @Author tanghj
* @Date 2021/2/24 11:03
*/
public class LocalElogService implements ILocalElogService {
private static final Logger logger = LoggerFactory.getLogger(LocalElogService.class);
private LocalElogAopDaoMapper getLocalElogAopDaoMapper() {
return MapperProxyFactory.getProxy(LocalElogAopDaoMapper.class);
}
// private RestHighLevelClient client;
//
// private LazyRollBack lazyRollBack;
//数据库类型
private static final String databaseId = new RecordSet().getDBType();
/**
* @param context
* @param <T>
* @return
*/
@Override
public <T> int insertLocalElog(LoggerContext<T> context) {
// logger.error("接收到的数据context:{}",JSONObject.toJSONString(context));
// logger.info("接收到数据的时间log_date:{}",context.getDate());
if (StringUtils.isEmpty(context.getUuid())) {
context.setUuid(UUID.randomUUID().toString().replace("-", ""));
}
String cusColumns = "";
String cusValus = "";
if (context.getCustomInfo() != null) {
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(context.getCustomInfo()));
List<String> clobFieldList = context.getClobFieldList();
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
String keystr = custom.getString(key);
//如果keystr包含单引号将单引号去掉
if (StringUtils.isNotEmpty(keystr) && keystr.contains("'")) {
keystr = keystr.replace("'", "''");
}
//如果是Oracle数据库
if (ElogConsts.ORACLE.equals(databaseId)) {
//clob字段集合不为空且包含此字段
if (!CollectionUtils.isEmpty(clobFieldList) && clobFieldList.contains(key)) {
String clobColumnStr = ElogUtils.handleClobColumn(keystr);
cusValus = cusValus + ",TO_CLOB( " + clobColumnStr + " )";
} else if (checkStrIsDate(keystr)) {
//并且字符串为时间类型格式 则进行特殊处理
cusValus = cusValus + ",TO_DATE('" + keystr + "', 'SYYYY-MM-DD HH24:MI:SS')";
} else {
cusValus = cusValus + ",'" + keystr + "'";
}
} else {
cusValus = cusValus + ",'" + keystr + "'";
}
}
}
normalizationContext(context);
String tableName = context.getModuleName() + "_" + context.getFunctionName() + "logs";
//context.setId(IdGenerator.generate());
Integer id = getLocalElogAopDaoMapper().queryElogContextById(context.getId(), tableName);
if (id != null) {
return 1;
}
// logger.info("插入前的数据context:{}",JSONObject.toJSONString(context));
int count = getLocalElogAopDaoMapper().insertElogContext(context, cusColumns, cusValus, tableName);
if (context.getDetailContexts() != null) {
String detailTableName = context.getModuleName() + "_" + context.getFunctionName() + "logs_detail";
insertBatchDetailPrepared(detailTableName, context);
}
return count;
}
/**
*
*
* @param detailTableName
* @param context
*/
private void insertBatchDetailPrepared(String detailTableName, LoggerContext context) {
// 用mapper
//分两种 有无自定义字段
List<LoggerDetailContext> detailContexts = context.getDetailContexts();
Boolean hasCustonInfo = false;
String cusColumns = "";
if (Objects.nonNull(detailContexts.get(0).getCustomDetailInfo())) {
hasCustonInfo = true;
//有自定义明细字段
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(detailContexts.get(0).getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
}
}
for (LoggerDetailContext detailContext : detailContexts) {
if (StringUtils.isNotEmpty(detailContext.getNewValue())) {
String str = detailContext.getNewValue().replaceAll("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}]", "");
detailContext.setNewValue(str);
}
if (StringUtils.isNotEmpty(detailContext.getOldValue())) {
String str = detailContext.getOldValue().replaceAll("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}]", "");
detailContext.setOldValue(str);
}
if (StringUtils.isNotEmpty(detailContext.getNewRealValue())) {
String str = detailContext.getNewRealValue().replaceAll("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}]", "");
detailContext.setNewRealValue(str);
}
if (StringUtils.isNotEmpty(detailContext.getOldRealValue())) {
String str = detailContext.getOldRealValue().replaceAll("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}]", "");
detailContext.setOldRealValue(str);
}
detailContext.setTenant_key(context.getTenant_key());
detailContext.setCreate_time(new Date());
detailContext.setUpdate_time(new Date());
detailContext.setCreator(context.getLogOperator());
detailContext.setId(IdGenerator.generate());
if (hasCustonInfo) {
String cusValus = "";
//如果有明细
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(detailContext.getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
String keystr = custom.getString(key);
//如果keystr包含单引号将单引号去掉
if (StringUtils.isNotEmpty(keystr) && keystr.contains("'")) {
keystr = keystr.replace("'", "''");
}
cusValus = cusValus + ",'" + keystr + "'";
}
detailContext.setCusValus(cusValus);
}
}
if (hasCustonInfo) {
getLocalElogAopDaoMapper().insertElogDetailPreparedHasCustonInfo(detailTableName, detailContexts, context.getUuid(), cusColumns);
} else {
getLocalElogAopDaoMapper().insertElogDetailPrepared(detailTableName, detailContexts, context.getUuid());
}
}
private <T> void normalizationContext(LoggerContext<T> context) {
String params = "";
if (StringUtils.isNotEmpty(context.getParamsStr())) {
params = context.getParamsStr();
} else if (context.getParams() != null) {
params = ElogUtils.compress(JSONObject.toJSONString(context.getParams()));
}
context.setParamsStr(params);
if (StringUtils.isBlank(context.getCancelContextStr())) {
context.setCancelContextStr(context.getCancelContext() == null ? "" : JSONObject.toJSONString(context.getCancelContext()));
}
if (StringUtils.isBlank(context.getRedoContextStr())) {
context.setRedoContextStr(context.getRedoContext() == null ? "" : JSONObject.toJSONString(context.getRedoContext()));
}
if (StringUtils.isEmpty(context.getOperatedesc())) {
context.setOperatedesc("");
} else {
//todo 兼容emojo特殊字符 没有时间 先暴力替换
String str = context.getOperatedesc().replaceAll("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}]", "");
context.setOperatedesc(str);
}
if (Objects.isNull(context.getDate())) {
context.setDate(new Date());
}
if (StringUtils.isEmpty(context.getOperator())) {
context.setLogOperator(-1l);
} else {
context.setLogOperator(Long.parseLong(context.getOperator()));
}
if (StringUtils.isEmpty(context.getTargetId())) {
context.setLogTargetid(-1l);
} else {
context.setLogTargetid(Long.parseLong(context.getTargetId()));
}
if (StringUtils.isEmpty(context.getClientIp())) {
context.setClientIp("127.0.0.1");
}
if (Objects.isNull(context.getCreate_time())) {
context.setCreate_time(new Date());
}
if (Objects.isNull(context.getUpdate_time())) {
context.setUpdate_time(new Date());
}
if (Objects.isNull(context.getDelete_type())) {
context.setDelete_type(0);
}
}
private void insertBatchDetailSql(String detailTableName, LoggerContext context) {
String standardField = "id, mainid, uuid, tablename, fieldname, newvalue, oldvalue, fielddesc, showorder, dataid, belongDataid, isDetail, tenant_key,creator, newRealValue, oldRealValue,tableNameDesc, tableNameLabelId,fieldNameLabelId, create_time, update_time";
Boolean hasCustonInfo = false;
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ").append(detailTableName).append("(").append(standardField);
//List<LoggerDetailContext> collect = detailContexts.stream().filter(s -> Objects.nonNull(s.getCustomDetailInfo())).collect(Collectors.toList());
List<LoggerDetailContext> detailContexts = context.getDetailContexts();
if (Objects.nonNull(detailContexts.get(0).getCustomDetailInfo())) {
hasCustonInfo = true;
//有自定义明细字段
String cusColumns = "";
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(detailContexts.get(0).getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
}
sb.append(cusColumns);
}
sb.append(")");
if ("oracle".equalsIgnoreCase(databaseId)) {
sb.append(" ").append(String.join(" UNION ALL ", getBatchInsertValue(context, hasCustonInfo, true)));
} else {
sb.append(" VALUES ").append(String.join(",", getBatchInsertValue(context, hasCustonInfo, false)));
}
try {
getLocalElogAopDaoMapper().batchInsertDetail(sb.toString());
} catch (Exception e) {
logger.error("明细批量添加sql是:{},批量插入明细失败,{}", sb.toString(), e.getMessage(), e);
}
}
private List<String> getBatchInsertValue(LoggerContext context, boolean hasCustomInfo, boolean isOracle) {
LocalDateTime localDateTime = LocalDateTime.now();
String nowDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
List<LoggerDetailContext> detailContexts = context.getDetailContexts();
List<String> batchValue = new ArrayList<>();
for (LoggerDetailContext detailContext : detailContexts) {
detailContext.setTenant_key(context.getTenant_key());
detailContext.setCreator(context.getLogOperator());
detailContext.setId(IdGenerator.generate());
StringBuilder sb = new StringBuilder();
sb.append(isOracle ? " SELECT " : " ( ");
sb.append(detailContext.getId())
.append(",'").append(context.getUuid()).append("'")
.append(",'").append(detailContext.getUuid()).append("'")
.append(",'").append(detailContext.getTableName()).append("'")
.append(",'").append(detailContext.getFieldName()).append("'")
.append(",'").append(transferString(detailContext.getNewValue())).append("'")
.append(",'").append(transferString(detailContext.getOldValue())).append("'")
.append(",'").append(detailContext.getFieldDesc()).append("'")
.append(",'").append(detailContext.getShoworder()).append("'")
.append(",'").append(detailContext.getDataid()).append("'")
.append(",'").append(detailContext.getBelongDataid()).append("'")
.append(",'").append(detailContext.getIsDetail()).append("'")
.append(",'").append(detailContext.getTenant_key()).append("'")
.append(",'").append(detailContext.getCreator()).append("'")
.append(",'").append(transferString(detailContext.getNewRealValue())).append("'")
.append(",'").append(transferString(detailContext.getOldRealValue())).append("'")
.append(",'").append(detailContext.getTableNameDesc()).append("'")
.append(",'").append(detailContext.getTableNameLabelId()).append("'")
.append(",'").append(detailContext.getFieldNameLabelId()).append("'")
.append(",").append(handleValue(nowDate, databaseId))
.append(",").append(handleValue(nowDate, databaseId));
if (hasCustomInfo) {
String cusValus = "";
//如果有明细
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(detailContext.getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
String keystr = custom.getString(key);
//如果keystr包含单引号将单引号去掉
if (StringUtils.isNotEmpty(keystr) && keystr.contains("'")) {
keystr = keystr.replace("'", "''");
}
cusValus = cusValus + ",'" + keystr + "'";
}
sb.append(cusValus);
}
String sql = isOracle ? sb.append(" from dual ").toString() : sb.append(")").toString();
batchValue.add(sql);
}
return batchValue;
}
private String transferString(String str) {
if (StringUtils.isNotEmpty(str)) {
str = str.replaceAll("#\\{", "\\\\\\\\#{");
if (str.contains("'")) {
str = str.replace("'", "''");
}
}
return str;
}
private String handleValue(String nowDate, String databaseId) {
switch (databaseId) {
case "mysql":
return "'" + nowDate + "'";
case "oracle":
return "TO_DATE('" + nowDate + "','YYYY-MM-DD HH24:MI:SS')";
case "sqlserver":
return "'" + nowDate + "'";
case "postgresql":
return "'" + nowDate + "'";
}
return nowDate;
}
// private <T> void insertESElogCenter(LoggerContext<T> context, String customInfo, String tableName) {
// //将数据转换为ES的数据格式
// LogESDoc logESDoc = LogESDoc.context2Doc(context, customInfo, tableName);
// String json = JSON.toJSONString(logESDoc);
// String elogESTableName = ElogEsUtils.getElogESTableName(true, ElogEsUtils.getDateStr(context.getDate()));
// IndexRequest indexRequest = new IndexRequest(elogESTableName).id(logESDoc.getId().toString());
// indexRequest.source(json, XContentType.JSON);
//
// try {
// client.index(indexRequest, RequestOptions.DEFAULT);
// } catch (IOException e) {
//// logger.info("主表数据添加失败:{}",e.getMessage());
// }
// }
@Override
public <T> int insertElogDetail(LoggerDetailContext<T> loggerDetailContext, String mainId, String detailTableName) {
String cusColumns = "";
String cusValus = "";
if (loggerDetailContext.getCustomDetailInfo() != null) {
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(loggerDetailContext.getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
String keystr = custom.getString(key);
//如果keystr包含单引号将单引号去掉
if (StringUtils.isNotEmpty(keystr) && keystr.contains("'")) {
keystr = keystr.replace("'", "''");
}
cusValus = cusValus + ",'" + keystr + "'";
}
}
loggerDetailContext.setId(IdGenerator.generate());
return getLocalElogAopDaoMapper().insertElogDetail(loggerDetailContext, mainId, cusColumns, cusValus, detailTableName);
}
// @Override
// public <T> void rollBackElog(LoggerContext<T> context) {
// //根据ID 判断数据是否存在
//
// String tableName = getElogTableName(context.getModuleName(), context.getFunctionName());
// Integer id = getLocalElogAopDaoMapper().queryElogContextById(context.getId(), tableName);
// //没查到就直接返回
// if (id == null) {
// lazyRollBack.delayedRollBack(context);
// return;
// }
// getLocalElogAopDaoMapper().rollBackElogById(context.getId(), tableName);
//
//// if (context.getDetailContexts() != null) {
// String detailTableName = context.getModuleName() + "_" + context.getFunctionName() + "logs_detail";
// //根据uuid回滚
// getLocalElogAopDaoMapper().rollBackDetailElogByUUID(context.getUuid(), detailTableName);
//// }
//
//
// }
/**
*
*/
public static Boolean checkStrIsDate(String str) {
if (StringUtils.isBlank(str)) {
return false;
} else {
try {
LocalDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return true;
} catch (Exception e) {
return false;
}
}
}
private String getElogTableName(String moduleName, String functionName) {
// List<String> list = Arrays.asList("meetingTopic", "meetingService", "meetingDecision", "meetingSign", "meetingSignSet", "meetingMember", "meetingShare");
// if (list.contains(moduleName)) {
// return "meeting"+ "_" + functionName + "logs";
// }
return moduleName + "_" + functionName + "logs";
}
}