---数据服务操作增加操作对象生命周期
This commit is contained in:
@ -0,0 +1,7 @@
|
||||
package com.xjrsoft.module.dev.dto;
|
||||
|
||||
import com.xjrsoft.common.page.PageInput;
|
||||
|
||||
public class Testfrom3ModalDto extends PageInput {
|
||||
|
||||
}
|
||||
@ -13,6 +13,7 @@ import com.xjrsoft.common.page.PageOutput;
|
||||
import com.xjrsoft.common.model.result.R;
|
||||
import com.xjrsoft.common.utils.VoToColumnUtil;
|
||||
import com.xjrsoft.module.dev.dto.AddTestfrom3Dto;
|
||||
import com.xjrsoft.module.dev.dto.Testfrom3ModalDto;
|
||||
import com.xjrsoft.module.dev.dto.UpdateTestfrom3Dto;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
@ -34,6 +35,8 @@ import com.xjrsoft.module.dev.vo.Testfrom3Vo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import shade.powerjob.com.google.common.collect.Lists;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@ -72,6 +75,41 @@ public class Testfrom3Controller {
|
||||
PageOutput<Testfrom3PageVo> pageOutput = ConventPage.getPageOutput(page, Testfrom3PageVo.class);
|
||||
return R.ok(pageOutput);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/modal")
|
||||
@ApiOperation(value="Testfrom3模态框接口")
|
||||
public R modal(@Valid Testfrom3ModalDto dto){
|
||||
Object resultData = null;
|
||||
List<Testfrom3PageVo> listData = null;
|
||||
LambdaQueryWrapper<Testfrom3> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper
|
||||
.like(StrUtil.isNotBlank(dto.getDanXingWenBen8163()),Testfrom3::getDanXingWenBen8163,dto.getDanXingWenBen8163())
|
||||
.like(StrUtil.isNotBlank(dto.getDanXingWenBen3634()),Testfrom3::getDanXingWenBen3634,dto.getDanXingWenBen3634())
|
||||
.like(StrUtil.isNotBlank(dto.getDanXingWenBen5097()),Testfrom3::getDanXingWenBen5097,dto.getDanXingWenBen5097())
|
||||
.orderByDesc(Testfrom3::getId)
|
||||
.select(Testfrom3.class,x -> VoToColumnUtil.fieldsToColumns(Testfrom3PageVo.class).contains(x.getProperty()));
|
||||
if(dto.isPage()) {
|
||||
|
||||
IPage<Testfrom3> page = testfrom3Service.page(ConventPage.getPage(dto), queryWrapper);
|
||||
PageOutput<Testfrom3PageVo> pageOutput = ConventPage.getPageOutput(page, Testfrom3PageVo.class);
|
||||
resultData = pageOutput;
|
||||
listData = pageOutput.getList();
|
||||
}else {
|
||||
List<Testfrom3> list = testfrom3Service.list(queryWrapper);
|
||||
if(list==null) {
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
listData = BeanUtil.copyToList(list,Testfrom3PageVo.class);
|
||||
resultData = listData;
|
||||
}
|
||||
|
||||
if(dto.getId()!=null && dto.getId().longValue() > 0) {
|
||||
Testfrom3 selected = testfrom3Service.getById(dto.getId());
|
||||
listData.add(BeanUtil.toBean(selected,Testfrom3PageVo.class));
|
||||
}
|
||||
return R.ok(resultData);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "/info")
|
||||
@ApiOperation(value="根据id查询Testfrom3信息")
|
||||
@ -144,4 +182,5 @@ public class Testfrom3Controller {
|
||||
|
||||
return R.fileStream(resultBot.toByteArray(), "Testfrom3" + ExcelTypeEnum.XLSX.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.xjrsoft.module.dev.dto;
|
||||
|
||||
import com.xjrsoft.common.page.PageInput;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @title: 分页查询入参
|
||||
* @Author 管理员
|
||||
* @Date: 2025-09-25
|
||||
* @Version 1.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Testfrom3ModalDto extends PageInput {
|
||||
|
||||
/**
|
||||
* @Fields {todo}(用一句话描述这个变量表示什么)
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 单行文本
|
||||
*/
|
||||
@ApiModelProperty("是否分页")
|
||||
private boolean page = true;
|
||||
|
||||
@ApiModelProperty("选中数据Id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 单行文本
|
||||
*/
|
||||
@ApiModelProperty("单行文本")
|
||||
private String danXingWenBen8163;
|
||||
/**
|
||||
* 单行文本
|
||||
*/
|
||||
@ApiModelProperty("单行文本")
|
||||
private String danXingWenBen3634;
|
||||
/**
|
||||
* 单行文本
|
||||
*/
|
||||
@ApiModelProperty("单行文本")
|
||||
private String danXingWenBen5097;
|
||||
|
||||
}
|
||||
@ -4,5 +4,5 @@ package com.xjrsoft.module.datalog.vo;
|
||||
* 操作类型枚举
|
||||
*/
|
||||
public enum OperationType {
|
||||
INSERT, UPDATE, DELETE
|
||||
INSERT, UPDATE, DELETE,DISABLE,ENABLE
|
||||
}
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
|
||||
import com.xjrsoft.module.datalog.vo.OperationType;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2025年10月30日 上午9:27:17
|
||||
* @Description: 数据操作上下文
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
public class DataOperationContent<T> {
|
||||
|
||||
private LogTableInfo tabInfo;
|
||||
|
||||
private OperationType type;
|
||||
|
||||
private T obj;
|
||||
|
||||
private T oldObj;
|
||||
|
||||
private Throwable error;
|
||||
|
||||
private DataOperationContent(LogTableInfo tabInfo,OperationType type, T obj, T oldObj) {
|
||||
super();
|
||||
this.tabInfo = tabInfo;
|
||||
this.type = type;
|
||||
this.obj = obj;
|
||||
this.oldObj = oldObj;
|
||||
}
|
||||
|
||||
public static <T>DataOperationContent<T> of(LogTableInfo tabInfo,OperationType type, T obj, T oldObj) {
|
||||
return new DataOperationContent<T>(tabInfo, type, obj,oldObj);
|
||||
}
|
||||
|
||||
|
||||
public boolean isError() {
|
||||
return error!=null;
|
||||
}
|
||||
|
||||
|
||||
public boolean success() {
|
||||
return error==null;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tabInfo.getTableName();
|
||||
}
|
||||
|
||||
|
||||
public long getIdValue() {
|
||||
return tabInfo.getIdValue(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2025年10月30日 上午9:22:22
|
||||
* @Description: 数据的生命周期接口
|
||||
*/
|
||||
public interface DataOperationListener<T> {
|
||||
|
||||
/**
|
||||
* @Description: 操作后
|
||||
* @param content 操作上下文
|
||||
* @return T 返回类型
|
||||
*/
|
||||
T before(DataOperationContent<T> content);
|
||||
|
||||
/**
|
||||
* @Description: 操作前
|
||||
* @param obj
|
||||
* @return T 返回类型
|
||||
*/
|
||||
T after(DataOperationContent<T> content);
|
||||
|
||||
|
||||
/**
|
||||
* @Description: TODO(这里用一句话描述这个方法的作用)
|
||||
* @param e
|
||||
* @return void 返回类型
|
||||
*/
|
||||
void onError(DataOperationContent<T> content);
|
||||
|
||||
|
||||
void onFinally(DataOperationContent<T> content);
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.pictc.datalog;
|
||||
|
||||
import com.xjrsoft.module.common.db.utils.CommonCallUtils;
|
||||
import com.xjrsoft.module.datalog.vo.OperationType;
|
||||
|
||||
public class DefaultDataOperationListener<T> implements DataOperationListener<T> {
|
||||
|
||||
@Override
|
||||
public T before(DataOperationContent<T> content) {
|
||||
if(content.getType()==OperationType.DELETE) {
|
||||
CommonCallUtils.deleteBefore(content.getTableName(),content.getIdValue());
|
||||
}else if(content.getType()==OperationType.DISABLE){
|
||||
CommonCallUtils.deleteBefore(content.getTableName(),content.getIdValue());
|
||||
}else if(content.getType()==OperationType.ENABLE){
|
||||
CommonCallUtils.enableBefore(content.getTableName(),content.getIdValue());
|
||||
}
|
||||
return content.getObj();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T after(DataOperationContent<T> content) {
|
||||
if(content.getType()==OperationType.INSERT || content.getType()==OperationType.UPDATE) {
|
||||
CommonCallUtils.saveAfter(content.getTableName(),content.getIdValue());
|
||||
}
|
||||
return content.getObj();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(DataOperationContent<T> content) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinally(DataOperationContent<T> content) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,7 +9,6 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
@ -26,34 +25,29 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import com.esotericsoftware.kryo.kryo5.minlog.Log;
|
||||
import com.google.api.client.util.Sets;
|
||||
import com.pictc.annotations.datalog.JoinCaseType;
|
||||
import com.pictc.annotations.datalog.JoinValueType;
|
||||
import com.pictc.annotations.datalog.LogJoin;
|
||||
import com.pictc.annotations.datalog.LogJoinColumn;
|
||||
import com.pictc.annotations.datalog.ValueDirectionType;
|
||||
import com.pictc.converts.ConverUtil;
|
||||
import com.pictc.datalog.DataOperationContent;
|
||||
import com.pictc.datalog.DataOperationListener;
|
||||
import com.pictc.datalog.DefaultDataOperationListener;
|
||||
import com.pictc.datalog.LogFieldInfo;
|
||||
import com.pictc.datalog.LogJoinInfo;
|
||||
import com.pictc.datalog.LogTableInfo;
|
||||
@ -63,12 +57,12 @@ import com.pictc.exceptions.OrmException;
|
||||
import com.pictc.jdbc.JdbcContext;
|
||||
import com.pictc.jdbc.ResultSetUtils;
|
||||
import com.pictc.jdbc.model.JdbcParam;
|
||||
import com.xjrsoft.common.enums.YesOrNoEnum;
|
||||
import com.xjrsoft.common.exception.BusinessException;
|
||||
import com.xjrsoft.common.utils.SecureUtil;
|
||||
import com.xjrsoft.module.common.db.utils.CommonCallUtils;
|
||||
import com.xjrsoft.module.datalog.entity.DataChangeLog;
|
||||
import com.xjrsoft.module.datalog.entity.json.FieldChange;
|
||||
import com.xjrsoft.module.datalog.service.DatalogService;
|
||||
import com.xjrsoft.module.datalog.mapper.DatalogMapper;
|
||||
import com.xjrsoft.module.datalog.vo.DataChangeLogVo;
|
||||
import com.xjrsoft.module.datalog.vo.OperationType;
|
||||
import com.xjrsoft.module.organization.dto.UserDto;
|
||||
@ -91,56 +85,15 @@ public class DataLogTools {
|
||||
|
||||
private static Object lock = new Object();
|
||||
|
||||
public static final String SQL_HAS_TABLE = "select count(*) from log_table_info where tbl_name = ?";
|
||||
|
||||
public static final String SQL_INST_TABLE = "INSERT INTO log_table_info (tbl_name) VALUES (?);";
|
||||
|
||||
public static final String SQL_LOG_TABLE_LIST = "select tbl_name FROM log_table_info";
|
||||
|
||||
public static final String SQL_PLACEHOLDER = "\\$\\{TBL_NAME\\}";
|
||||
|
||||
public static final String[] SQL_CREATE_TABLE = {
|
||||
"CREATE TABLE ${TBL_NAME} (\r\n" +
|
||||
" id VARCHAR(32) NOT NULL,\r\n" +
|
||||
" flow_id VARCHAR(32),\r\n" +
|
||||
" pid VARCHAR(32) DEFAULT '#',\r\n" +
|
||||
" entity_class_name VARCHAR(255),\r\n" +
|
||||
" bus_name VARCHAR(100),\r\n" +
|
||||
" entity_id BIGINT,\r\n" +
|
||||
" field_changes TEXT,\r\n" +
|
||||
" operation_type VARCHAR(20),\r\n" +
|
||||
" operator_id BIGINT,\r\n" +
|
||||
" operator_name VARCHAR(100),\r\n" +
|
||||
" operation_time TIMESTAMPTZ,\r\n" +
|
||||
" operation_ip VARCHAR(50),\r\n" +
|
||||
" PRIMARY KEY (id)\r\n" +
|
||||
" );",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"flow_id\" IS '流水id';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"pid\" IS '父表ID,根节点#';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"entity_class_name\" IS '实体类名称(全类名)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"bus_name\" IS '业务名称';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"entity_id\" IS '操作的实体ID(主键值)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"field_changes\" IS '属性值记录(JSON格式存储字段变更详情)';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_type\" IS '操作类型:INSERT-新增,UPDATE-修改,DELETE-删除';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operator_id\" IS '操作人ID';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operator_name\" IS '操作人姓名';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_time\" IS '操作时间';",
|
||||
"COMMENT ON COLUMN ${TBL_NAME}.\"operation_ip\" IS '操作IP地址';",
|
||||
"CREATE INDEX idx_${TBL_NAME}_enityt_id ON ${TBL_NAME} (entity_id)"
|
||||
};
|
||||
|
||||
public static final String SQL_INSERT = "INSERT INTO ${TBL_NAME} (\r\n" +
|
||||
" id, flow_id, pid, entity_class_name, bus_name, \r\n" +
|
||||
" entity_id, field_changes, operation_type, operator_id, \r\n" +
|
||||
" operator_name, operation_time, operation_ip\r\n" +
|
||||
") VALUES (?,?,?,?,?,?,?,?,?,?,?,?);";
|
||||
|
||||
|
||||
public static final String SQL_LIST = "SELECT * FROM ${TBL_NAME} WHERE entity_id = ? ORDER BY operation_time DESC, flow_id DESC";
|
||||
|
||||
public static final Set<String> excludeFields = SetUtils.of("id","tenantId","dataVersion","createUserId","createDate","modifyUserId","modifyDate","modifyDate","deleteMark");
|
||||
|
||||
private static DatalogMapper logDbService;
|
||||
|
||||
@Autowired
|
||||
public void setLogDbService(DatalogMapper logDbService) {
|
||||
DataLogTools.logDbService = logDbService;
|
||||
}
|
||||
|
||||
public static DataChangeLog createLog(Class<?> klazz,OperationType type) {
|
||||
DataChangeLog createLog = createLog(klazz, type, null);
|
||||
return createLog.setFlowId(IdUtil.getSnowflakeNextIdStr());
|
||||
@ -183,6 +136,10 @@ public class DataLogTools {
|
||||
}
|
||||
|
||||
public static <T>T insert(T entity) {
|
||||
return insert(entity, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
public static <T>T insert(T entity,DataOperationListener<T> listener) {
|
||||
Class<? extends Object> klazz = entity.getClass();
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.INSERT);
|
||||
@ -190,108 +147,209 @@ public class DataLogTools {
|
||||
initJoinValue(entity,tabInfo,null);
|
||||
Long idValue = tabInfo.getIdValue(entity);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
mapper.insert(BeanUtil.toBean(entity,tabInfo.getEntityType()));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.INSERT,tabInfo,join,entity);
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.INSERT,entity,null);
|
||||
listener.before(content);
|
||||
}
|
||||
|
||||
try {
|
||||
mapper.insert(BeanUtil.toBean(entity,tabInfo.getEntityType()));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.INSERT,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
|
||||
saveLogs(tabInfo,logs);
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
}finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public static <T>T update(T dto) {
|
||||
return update(dto, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
|
||||
public static <T>T update(T dto,DataOperationListener<T> listener) {
|
||||
Class<? extends Object> klazz = dto.getClass();
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
|
||||
Long idValue = tabInfo.getIdValue(dto);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object old = findById(klazz, idValue);
|
||||
if(old!=null) {
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.UPDATE);
|
||||
initJoinValue(dto,tabInfo,null);
|
||||
|
||||
mapper.updateById(tabInfo.toEntity(dto));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,dto,old);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.UPDATE,tabInfo,join,dto);
|
||||
T old = findById(klazz, idValue);
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.UPDATE,dto,old);
|
||||
listener.before(content);
|
||||
}
|
||||
try {
|
||||
if(old!=null) {
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.UPDATE);
|
||||
initJoinValue(dto,tabInfo,null);
|
||||
|
||||
mapper.updateById(tabInfo.toEntity(dto));
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,dto,old);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.UPDATE,tabInfo,join,dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
}else {
|
||||
throw new OrmException("数据不存在");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
}else {
|
||||
throw new OrmException("数据不存在");
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static <T>T delete(T dto) {
|
||||
return delete(dto, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
public static <T>T delete(T entity) {
|
||||
|
||||
public static <T>T delete(T entity,DataOperationListener<T> listener) {
|
||||
Class<? extends Object> klazz = entity.getClass();
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
Long idValue = tabInfo.getIdValue(entity);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(idValue);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
delete(entity, tabInfo, mapper);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
T old = findById(klazz, idValue);
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.DELETE,old,null);
|
||||
listener.before(content);
|
||||
}
|
||||
|
||||
try {
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(idValue);
|
||||
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
delete(entity, tabInfo, mapper);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
}finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public static boolean deleteByIds(Class<?> klazz, @Valid List<Long> ids) {
|
||||
public static <T>boolean deleteByIds(Class<T> klazz, @Valid List<Long> ids) {
|
||||
return deleteByIds(klazz, ids, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
|
||||
public static <T>boolean deleteByIds(Class<T> klazz, @Valid List<Long> ids,DataOperationListener<T> listener) {
|
||||
for (Long id : ids) {
|
||||
deleteById(klazz, id);
|
||||
deleteById(klazz, id,listener);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T>T deleteById(Class<T> klazz,Long id) {
|
||||
return deleteById(klazz,id,new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
public static <T>T deleteById(Class<T> klazz,Long id,DataOperationListener<T> listener) {
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
T entity = findById(klazz, id);
|
||||
if(entity==null) return null;
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.DELETE,entity,null);
|
||||
listener.before(content);
|
||||
}
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
|
||||
delete(entity, tabInfo, mapper);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
try {
|
||||
delete(entity, tabInfo, mapper);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DELETE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,entity,null);
|
||||
logs.add(datalog);
|
||||
List<LogJoinInfo> joins = tabInfo.getJoins();
|
||||
if(!CollectionUtils.isNotEmpty(joins)) {
|
||||
for (LogJoinInfo join : joins) {
|
||||
if(join.getJoin().caseType()==JoinCaseType.FULL) {
|
||||
buildJoins(logs,datalog,OperationType.DELETE,tabInfo,join,entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
}finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@ -304,64 +362,117 @@ public class DataLogTools {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean enable(Class<?> klazz, @Valid List<Long> ids) {
|
||||
public static <T>boolean enable(Class<T> klazz,@Valid List<Long> ids) {
|
||||
return enable(klazz, ids, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
|
||||
public static <T>boolean enable(Class<T> klazz, @Valid List<Long> ids,DataOperationListener<T> listener) {
|
||||
for (Long id : ids) {
|
||||
enableById(klazz, id);
|
||||
enableById(klazz, id,listener);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T>T enableById(Class<T> klazz,Long id) {
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object entity = findNativeById(klazz, id);
|
||||
if(entity==null) return null;
|
||||
T old = BeanUtils.newInstance(klazz);
|
||||
BeanUtil.copyProperties(entity,old,true);
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
BeanUtils.setFieldValue("valid", YesOrNoEnum.YES.getTextCode(), entity);
|
||||
mapper.updateById(entity);
|
||||
T dto = (T)tabInfo.toDto(entity);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.UPDATE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,dto,tabInfo.toDto(old));
|
||||
logs.add(datalog);
|
||||
saveLogs(tabInfo,logs);
|
||||
return dto;
|
||||
return enableById(klazz, id, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
public static boolean disable(Class<?> klazz, @Valid List<Long> ids) {
|
||||
public static <T>T enableById(Class<T> klazz,Long id,DataOperationListener<T> listener) {
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
T old = findById(klazz, id);
|
||||
if(old==null) return null;
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.ENABLE,old,old);
|
||||
listener.before(content);
|
||||
}
|
||||
T entity = null;
|
||||
try {
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
CommonCallUtils.enableBefore(tabInfo.getTableName(),id);
|
||||
entity = findById(klazz, id);
|
||||
content.setObj(entity);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.ENABLE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,entity,old);
|
||||
logs.add(datalog);
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
}finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static <T>boolean disable(Class<T> klazz,@Valid List<Long> ids) {
|
||||
return disable(klazz, ids, new DefaultDataOperationListener<T>());
|
||||
}
|
||||
|
||||
|
||||
public static <T>boolean disable(Class<T> klazz, @Valid List<Long> ids,DataOperationListener<T> listener) {
|
||||
for (Long id : ids) {
|
||||
disableById(klazz, id);
|
||||
disableById(klazz, id,listener);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T>T disableById(Class<T> klazz,Long id) {
|
||||
public static <T>T disableById(Class<T> klazz,Long id,DataOperationListener<T> listener) {
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object entity = findNativeById(klazz, id);
|
||||
if(entity==null) return null;
|
||||
T old = BeanUtils.newInstance(klazz);
|
||||
BeanUtil.copyProperties(entity,old,true);
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
BeanUtils.setFieldValue("valid",YesOrNoEnum.NO.getTextCode(), entity);
|
||||
mapper.updateById(entity);
|
||||
T dto = (T)tabInfo.toDto(entity);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.UPDATE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,dto,tabInfo.toDto(old));
|
||||
logs.add(datalog);
|
||||
saveLogs(tabInfo,logs);
|
||||
return dto;
|
||||
T old = findById(klazz, id);
|
||||
if(old==null) return null;
|
||||
DataOperationContent<T> content = null;
|
||||
if(listener!=null) {
|
||||
content = DataOperationContent.of(tabInfo,OperationType.DISABLE,old,old);
|
||||
listener.before(content);
|
||||
}
|
||||
|
||||
T entity = null;
|
||||
try {
|
||||
List<DataChangeLog> logs = CollectionUtils.newArrayList();
|
||||
CommonCallUtils.enableBefore(tabInfo.getTableName(),id);
|
||||
entity = findById(klazz, id);
|
||||
content.setObj(entity);
|
||||
DataChangeLog datalog = createLog(klazz,OperationType.DISABLE);
|
||||
datalog.setEntityId(id);
|
||||
buildFields(datalog,tabInfo,entity,old);
|
||||
logs.add(datalog);
|
||||
if(listener!=null) {
|
||||
listener.after(content);
|
||||
}
|
||||
saveLogs(tabInfo,logs);
|
||||
} catch (Exception e) {
|
||||
if(listener!=null) {
|
||||
content.setError(e);
|
||||
listener.onError(content);
|
||||
}
|
||||
throw e;
|
||||
}finally {
|
||||
if(listener!=null) {
|
||||
listener.onFinally(content);
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public static <T>T findById(Class<T> klazz,Serializable id){
|
||||
public static <T>T findById(Class<?> klazz,Serializable id){
|
||||
return findById(klazz,id,false);
|
||||
}
|
||||
|
||||
public static <T>T findById(Class<T> klazz,Serializable id,boolean full){
|
||||
public static <T>T findById(Class<?> klazz,Serializable id,boolean full){
|
||||
LogTableInfo tabInfo = getAnnotation(klazz);
|
||||
BaseMapper mapper = MybatisTools.getMapper(tabInfo.getEntityType());
|
||||
Object old = mapper.selectById(id);
|
||||
@ -755,34 +866,35 @@ public class DataLogTools {
|
||||
public static void saveLogs(LogTableInfo tableInfo,List<DataChangeLog> logs) {
|
||||
String tableName = parseLogTableName(tableInfo);
|
||||
initTable(tableName);
|
||||
String sql = parseSql(SQL_INSERT, tableName);
|
||||
List<List<JdbcParam>> batchParams = CollectionUtils.newArrayList();
|
||||
Map<String, List<DataChangeLog>> pidMap = logs.stream().collect(Collectors.groupingBy(DataChangeLog::getPid));
|
||||
|
||||
|
||||
|
||||
// String sql = parseSql(SQL_INSERT, tableName);
|
||||
// List<List<JdbcParam>> batchParams = CollectionUtils.newArrayList();
|
||||
// Map<String, List<DataChangeLog>> pidMap = logs.stream().collect(Collectors.groupingBy(DataChangeLog::getPid));
|
||||
//
|
||||
// for (DataChangeLog item : logs) {
|
||||
// //没有改变的属性,且没有子表修改时跳过
|
||||
// if(!item.hasFieldChanges() && !hasChild(item, pidMap)) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// List<JdbcParam> params = CollectionUtils.newArrayList();
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getId()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getFlowId()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getPid()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getEntityClassName()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getBusName()));
|
||||
// params.add(JdbcParam.of(Types.BIGINT,long.class, item.getEntityId()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class,JSON.toJSONString(item.getFieldChanges())));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationType().name()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,long.class,item.getOperatorId()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperatorName()));
|
||||
// params.add(JdbcParam.of(Types.TIMESTAMP,Timestamp.class,item.getOperationTime()));
|
||||
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationIp()));
|
||||
// batchParams.add(params);
|
||||
// }
|
||||
// executeBatch(sql, batchParams);
|
||||
for (DataChangeLog item : logs) {
|
||||
//没有改变的属性,且没有子表修改时跳过
|
||||
if(!item.hasFieldChanges() && !hasChild(item, pidMap)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<JdbcParam> params = CollectionUtils.newArrayList();
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getFlowId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getPid()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getEntityClassName()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getBusName()));
|
||||
params.add(JdbcParam.of(Types.BIGINT,long.class, item.getEntityId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,JSON.toJSONString(item.getFieldChanges())));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationType().name()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,long.class,item.getOperatorId()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperatorName()));
|
||||
params.add(JdbcParam.of(Types.TIMESTAMP,Timestamp.class,item.getOperationTime()));
|
||||
params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationIp()));
|
||||
batchParams.add(params);
|
||||
logDbService.insertDataLog(tableName,item);
|
||||
}
|
||||
executeBatch(sql, batchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -794,11 +906,8 @@ public class DataLogTools {
|
||||
synchronized (lock) {
|
||||
//如果没有日志表时,重新创建
|
||||
if(!hasTable(tableName)) {
|
||||
for (int i = 0; i < SQL_CREATE_TABLE.length; i++) {
|
||||
execute(parseSql(SQL_CREATE_TABLE[i], tableName));
|
||||
}
|
||||
//将表名进行记录
|
||||
executeUpdate(SQL_INST_TABLE,ListUtils.ofArray(JdbcParam.ofString(tableName)));
|
||||
logDbService.createDatalogTable(tableName);
|
||||
logDbService.addTableInfo(tableName);
|
||||
logTables.add(tableName);
|
||||
log.info("新增数据日志表:{}",tableName);
|
||||
return true;
|
||||
@ -808,18 +917,14 @@ public class DataLogTools {
|
||||
}
|
||||
|
||||
|
||||
private static String parseSql(String sql,String tableName) {
|
||||
return sql.replaceAll(SQL_PLACEHOLDER,tableName);
|
||||
}
|
||||
|
||||
private static boolean hasTable(String tableName) {
|
||||
synchronized (lock) {
|
||||
if(logTables==null) {
|
||||
List<String> tabs = queryListPrimitive(SQL_LOG_TABLE_LIST,String.class, null);
|
||||
List<String> tabs = logDbService.getTableList();
|
||||
logTables = new HashSet<String>(tabs);
|
||||
}
|
||||
if(logTables.contains(tableName)) return true;
|
||||
Long count = queryPrimitive(SQL_HAS_TABLE,long.class,Lists.newArrayList(JdbcParam.ofString(tableName)));
|
||||
Long count = logDbService.getCountByTableName(tableName);
|
||||
boolean flag = count!=null && count > 0;
|
||||
if(flag) {
|
||||
logTables.add(tableName);
|
||||
@ -851,40 +956,41 @@ public class DataLogTools {
|
||||
if(initTable(tableName)) {
|
||||
return null;
|
||||
}
|
||||
List<DataChangeLog> result = CollectionUtils.newArrayList();
|
||||
String sql = parseSql(SQL_LIST, tableName);
|
||||
JdbcContext context = null;
|
||||
try {
|
||||
context = new JdbcContext(true,true);
|
||||
context.init(sql);
|
||||
context.setParams(ListUtils.ofArray(JdbcParam.ofLong(dataId)));
|
||||
ResultSet set = context.executeQuery();
|
||||
Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
while (set.next()) {
|
||||
DataChangeLog log = new DataChangeLog();
|
||||
log.setId(set.getString("id"));
|
||||
log.setFlowId(set.getString("flow_id"));
|
||||
log.setPid(set.getString("pid"));
|
||||
log.setEntityClassName(set.getString("entity_class_name"));
|
||||
log.setBusName(set.getString("bus_name"));
|
||||
log.setEntityId(set.getLong("entity_id"));
|
||||
log.setOperationType(OperationType.valueOf(set.getString("operation_type")));
|
||||
log.setOperationIp(set.getString("operation_ip"));
|
||||
log.setOperatorId(set.getLong("operator_id"));
|
||||
log.setOperatorName(set.getString("operator_name"));
|
||||
log.setOperationTime(ResultSetUtils.getObject(set,"operation_time",LocalDateTime.class));
|
||||
String json = set.getString("field_changes");
|
||||
if(StringUtils.isNotEmpty(json)) {
|
||||
log.setFieldChanges(JSON.parseArray(json).toJavaList(FieldChange.class));
|
||||
}
|
||||
result.add(log);
|
||||
}
|
||||
return toVo(result);
|
||||
} catch (SQLException e) {
|
||||
throw context.createException(e);
|
||||
} finally {
|
||||
context.end();
|
||||
}
|
||||
List<DataChangeLog> logs = logDbService.selectByDataId(tableName,dataId);
|
||||
return toVo(logs);
|
||||
// String sql = parseSql(SQL_LIST, tableName);
|
||||
// JdbcContext context = null;
|
||||
// try {
|
||||
// context = new JdbcContext(true,true);
|
||||
// context.init(sql);
|
||||
// context.setParams(ListUtils.ofArray(JdbcParam.ofLong(dataId)));
|
||||
// ResultSet set = context.executeQuery();
|
||||
// Map<String, String> names = ResultSetUtils.getMapColumns(set);
|
||||
// while (set.next()) {
|
||||
// DataChangeLog log = new DataChangeLog();
|
||||
// log.setId(set.getString("id"));
|
||||
// log.setFlowId(set.getString("flow_id"));
|
||||
// log.setPid(set.getString("pid"));
|
||||
// log.setEntityClassName(set.getString("entity_class_name"));
|
||||
// log.setBusName(set.getString("bus_name"));
|
||||
// log.setEntityId(set.getLong("entity_id"));
|
||||
// log.setOperationType(OperationType.valueOf(set.getString("operation_type")));
|
||||
// log.setOperationIp(set.getString("operation_ip"));
|
||||
// log.setOperatorId(set.getLong("operator_id"));
|
||||
// log.setOperatorName(set.getString("operator_name"));
|
||||
// log.setOperationTime(ResultSetUtils.getObject(set,"operation_time",LocalDateTime.class));
|
||||
// String json = set.getString("field_changes");
|
||||
// if(StringUtils.isNotEmpty(json)) {
|
||||
// log.setFieldChanges(JSON.parseArray(json).toJavaList(FieldChange.class));
|
||||
// }
|
||||
// result.add(log);
|
||||
// }
|
||||
// return toVo(result);
|
||||
// } catch (SQLException e) {
|
||||
// throw context.createException(e);
|
||||
// } finally {
|
||||
// context.end();
|
||||
// }
|
||||
}
|
||||
|
||||
private static List<DataChangeLogVo> toVo(List<DataChangeLog> list){
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
package com.xjrsoft.module.common.db.utils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.xjrsoft.module.common.db.service.CommonCallService;
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2025年10月30日 上午9:58:16
|
||||
* @Description: TODO(这里用一句话描述这个类的作用)
|
||||
*/
|
||||
@Component
|
||||
public class CommonCallUtils {
|
||||
|
||||
private static CommonCallService callService;
|
||||
|
||||
@Autowired
|
||||
public void setCallService(CommonCallService callService) {
|
||||
CommonCallUtils.callService = callService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
一、新增、修改记录时,在同一个事务里执行如下过程:
|
||||
1、更新表;
|
||||
2、调用数据库函数pc_表名.f_save(表主键);
|
||||
3、函数返回非空、或者数据库异常时rollback,函数返回空时commit;
|
||||
* @param table 表名
|
||||
* @param id 表主键
|
||||
* @return String 返回类型 函数返回非空、或者数据库异常时rollback,函数返回空时commit;
|
||||
*/
|
||||
public static String saveAfter(String table,long id) {
|
||||
return callService.saveAfter(table, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
二、删除记录时,在同一个事务里执行如下过程:
|
||||
1、调用数据库函数pc_表名.f_delete(表主键);
|
||||
2、函数返回非空、或者数据库异常时rollback,函数返回空时commit;
|
||||
* @return
|
||||
* @return String 返回类型
|
||||
*/
|
||||
public static String deleteBefore(String table,Long id) {
|
||||
return callService.deleteBefore(table, id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
二、停用时,在同一个事务里执行如下过程:
|
||||
1、调用数据库函数pc_表名.f_off(表主键);
|
||||
2、函数返回非空、或者数据库异常时rollback,函数返回空时commit;
|
||||
* @return
|
||||
* @return String 返回类型
|
||||
*/
|
||||
public static String disableBefore(String table,Long id) {
|
||||
return callService.disableBefore(table, id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
1、调用数据库函数pc_表名.f_on(表主键);
|
||||
2、函数返回非空、或者数据库异常时rollback,函数返回空时commit;
|
||||
* @return
|
||||
* @return String 返回类型
|
||||
*/
|
||||
public static String enableBefore(String table,Long id) {
|
||||
return callService.enableBefore(table, id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -77,7 +77,7 @@ public class DataChangeLog implements Serializable{
|
||||
/**
|
||||
* 操作类型:INSERT-新增,UPDATE-修改,DELETE-删除
|
||||
*/
|
||||
@ApiModelProperty("操作类型:INSERT-新增,UPDATE-修改,DELETE-删除")
|
||||
@ApiModelProperty("操作类型:INSERT-新增,UPDATE-修改,DELETE-删除 ENABLE-启用 DISABLE-禁用")
|
||||
private OperationType operationType;
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
package com.xjrsoft.module.datalog.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.xjrsoft.module.datalog.entity.DataChangeLog;
|
||||
|
||||
/**
|
||||
* @author 张福财
|
||||
* @date 2025年10月30日 下午2:17:47
|
||||
* @Description: 数据日志操作
|
||||
*/
|
||||
@DS("datalog") //"data_log_sit"
|
||||
@Mapper
|
||||
public interface DatalogMapper extends BaseMapper<DataChangeLog> {
|
||||
|
||||
public static final String SQL_INSERT = "INSERT INTO \"data_log_sit\".${TBL_NAME} (\r\n" +
|
||||
" id, flow_id, pid, entity_class_name, bus_name, \r\n" +
|
||||
" entity_id, field_changes, operation_type, operator_id, \r\n" +
|
||||
" operator_name, operation_time, operation_ip\r\n" +
|
||||
") VALUES (#{data.id},#{data.flowId},#{data.pid},#{data.entityClassName},#{data.busName},#{data.entityId},"
|
||||
+ "#{data.fieldChanges},#{data.operationType},#{data.operatorId},#{data.operatorName},#{data.operationTime},#{data.operationIp});";
|
||||
|
||||
public static final String SQL_CREATE_TABLE =
|
||||
"CREATE TABLE \"data_log_sit\".${TBL_NAME} (\r\n" +
|
||||
" id VARCHAR(32) NOT NULL,\r\n" +
|
||||
" flow_id VARCHAR(32),\r\n" +
|
||||
" pid VARCHAR(32) DEFAULT '#',\r\n" +
|
||||
" entity_class_name VARCHAR(255),\r\n" +
|
||||
" bus_name VARCHAR(100),\r\n" +
|
||||
" entity_id BIGINT,\r\n" +
|
||||
" field_changes TEXT,\r\n" +
|
||||
" operation_type VARCHAR(20),\r\n" +
|
||||
" operator_id BIGINT,\r\n" +
|
||||
" operator_name VARCHAR(100),\r\n" +
|
||||
" operation_time TIMESTAMPTZ,\r\n" +
|
||||
" operation_ip VARCHAR(50),\r\n" +
|
||||
" PRIMARY KEY (id));\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"flow_id\" IS '流水id';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"pid\" IS '父表ID,根节点#';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"entity_class_name\" IS '实体类名称(全类名)';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"bus_name\" IS '业务名称';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"entity_id\" IS '操作的实体ID(主键值)';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"field_changes\" IS '属性值记录(JSON格式存储字段变更详情)';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"operation_type\" IS '操作类型:INSERT-新增,UPDATE-修改,DELETE-删除';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"operator_id\" IS '操作人ID';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"operator_name\" IS '操作人姓名';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"operation_time\" IS '操作时间';\r\n" +
|
||||
"COMMENT ON COLUMN \"data_log_sit\".${TBL_NAME}.\"operation_ip\" IS '操作IP地址';\r\n" +
|
||||
"CREATE INDEX idx_${TBL_NAME}_enityt_id ON \"data_log_sit\".${TBL_NAME} (entity_id);";
|
||||
|
||||
@DS("datalog")
|
||||
@Select("select count(*) from \"data_log_sit\".log_table_info where tbl_name = #{tableName}")
|
||||
long getCountByTableName(@Param("tableName") String name);
|
||||
|
||||
@DS("datalog")
|
||||
@Insert("INSERT INTO \"data_log_sit\".log_table_info (tbl_name) VALUES (#{tableName});")
|
||||
void addTableInfo(@Param("tableName") String tableName);
|
||||
|
||||
@DS("datalog")
|
||||
@Select("select tbl_name FROM \"data_log_sit\".log_table_info")
|
||||
List<String> getTableList();
|
||||
|
||||
@DS("datalog")
|
||||
@Insert(SQL_INSERT)
|
||||
void insertDataLog(@Param("TBL_NAME") String tableName,@Param("data") DataChangeLog data);
|
||||
|
||||
@DS("datalog")
|
||||
@Update(SQL_CREATE_TABLE)
|
||||
void createDatalogTable(@Param("TBL_NAME") String tableName);
|
||||
|
||||
@DS("datalog")
|
||||
@Select("SELECT * FROM \"data_log_sit\".${TBL_NAME} WHERE entity_id = #{id} ORDER BY operation_time DESC, flow_id DESC")
|
||||
List<DataChangeLog> selectByDataId(@Param("TBL_NAME") String tableName,@Param("id")Long id);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -4,6 +4,7 @@ import java.util.List;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.seata.spring.annotation.GlobalTransactional;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -16,12 +17,14 @@ import com.xjrsoft.module.datalog.vo.DataChangeLogVo;
|
||||
public class DatalogServiceImpl implements DatalogService{
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> T insert(T entity) {
|
||||
return DataLogTools.insert(entity);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> List<T> insertBatch(List<T> entitys) {
|
||||
List<T> res = Lists.newArrayList();
|
||||
@ -32,6 +35,7 @@ public class DatalogServiceImpl implements DatalogService{
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> boolean updateById(T entity) {
|
||||
DataLogTools.update(entity);
|
||||
@ -39,34 +43,42 @@ public class DatalogServiceImpl implements DatalogService{
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> T delete(T entity) {
|
||||
return DataLogTools.delete(entity);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> T deleteById(Class<T> klazz, long id) {
|
||||
return DataLogTools.deleteById(klazz, id);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> boolean deleteByIds(Class<T> klazz, @Valid List<Long> ids) {
|
||||
return DataLogTools.deleteByIds(klazz, ids);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> List<DataChangeLogVo> findLogsByEntityId(Class<T> klazz, long dataId) {
|
||||
return DataLogTools.findLogsByEntityId(klazz, dataId);
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> boolean enable(Class<T> klazz, @Valid List<Long> ids) {
|
||||
return DataLogTools.enable(klazz, ids);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@GlobalTransactional(rollbackFor = Exception.class) // Seata全局事务注解
|
||||
@Override
|
||||
public <T> boolean disable(Class<T> klazz, @Valid List<Long> ids) {
|
||||
return DataLogTools.disable(klazz, ids);
|
||||
|
||||
@ -102,7 +102,7 @@ public class CategoryController {
|
||||
@ApiOperation(value = "启用LngBCategory")
|
||||
@SaCheckPermission("category:enable")
|
||||
public R enable(@Valid @RequestBody List<Long> ids){
|
||||
return R.ok(categoryService.enable(ids));
|
||||
return R.ok(dataService.enable(UpdateLngBCategoryDto.class,ids));
|
||||
}
|
||||
|
||||
@PostMapping("/disable")
|
||||
|
||||
@ -121,7 +121,6 @@ public class CountryRegionController {
|
||||
@SaCheckPermission("countryRegion:delete")
|
||||
public R delete(@Valid @RequestBody List<Long> ids){
|
||||
return R.ok(dataService.deleteByIds(UpdateLngBRegionDto.class, ids));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.xjrsoft;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@ -14,6 +15,7 @@ import com.xjrsoft.common.annotation.UniqueNameGenerator;
|
||||
* 主数据服务---开发使用
|
||||
* 使用时集成到其它模块使用,不作为单独的服务
|
||||
*/
|
||||
@MapperScan("com.xjrsoft.module.*.mapper")
|
||||
@SpringBootApplication
|
||||
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||
@ComponentScan(nameGenerator = UniqueNameGenerator.class)
|
||||
|
||||
Reference in New Issue
Block a user