最近做了一个功能为用户信息修改添加审核功能,审核通过以后修改才会生效。一般的做法是修改的时候添加一条记录,审核通过以后再把修改记录更新到原始的记录中。
尝试了一种新的方式,用一张表记录更新的字段和值,审核通过以后把修改值更新到记录里面。这样做的优势在于在很多表都需要做更新审核的时候可以直接复用这个功能,不需要为每个更新添加修改逻辑。
首先创建一个表用于记录更新的字段和值,实体类:
public class UpdateDetail implements Serializable {
private static final long serialVersionUID=1L;
public UpdateDetail(String fieldName,String fieldValue){
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
@ApiModelProperty(value = "唯一标识")
@TableId(value = "id", type = IdType.ID_WORKER)
private Long id;
@ApiModelProperty(value = "外键关联")
private Long recId;
@ApiModelProperty(value = "字段名称")
private String fieldName;
@ApiModelProperty(value = "字段数值")
private String fieldValue;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}
用户页面修改:
使用反射记录更新的字段名称和值
public void updateUserBaseInfo(Param param) {
//校验参数
Long id = param.getId();
if (id == null) {
throw new CheckedException("ID不能为空");
}
UserUpdateUserBaseInfo targetUserBaseInfo = new UserUpdateUserBaseInfo();
BeanUtils.copyProperties(param, targetUserBaseInfo);
UserUpdateUserBaseInfo orgUserBaseInfo = lcCtrledConsMapper.getOneBaseInfo(id);
//获取修改字段信息
List<UpdateDetail> consDetailList = getConsDetailList(targetUserBaseInfo, orgUserBaseInfo);
if (consDetailList.isEmpty()) {
throw new CheckedException("信息未作修改,请确认后重试");
}
//查询没有提交的修改
List<UpdateRec> list = this.list(new QueryWrapper<UpdateRec>().eq("cons_id", id).eq("verify_status", 0).eq("submit_status", 0));
//没有可以直接添加
long recordId;
if (list.isEmpty()) {
recordId = SnowflakeUtil.getId();
UpdateRec UpdateRec = new UpdateRec();
UpdateRec.setConsId(param.getId());
UpdateRec.setId(recordId);
UpdateRec.setProcessId(SnowflakeUtil.getId());
UpdateRec.setVerifyStatus("0");
UpdateRec.setSubmitStatus("1");
this.save(UpdateRec);
} else {
//如果直接进行修改提交
UpdateRec UpdateRec = list.get(0);
UpdateRec.setSubmitStatus("1");
this.updateById(UpdateRec);
recordId = UpdateRec.getId();
}
for (UpdateDetail UpdateDetail : consDetailList) {
UpdateDetail.setRecId(recordId);
}
lcConsUpdateDetailService.saveBatch(consDetailList);
}
/**
* 对比真实数据和提交的数据生成记录
*
* @param targetUserBaseInfo 目标对象值
* @param orgUserBaseInfo 源对象值
* @return 记录对象
*/
private List<UpdateDetail> getConsDetailList(UserUpdateUserBaseInfo targetUserBaseInfo, UserUpdateUserBaseInfo orgUserBaseInfo) {
Class<? extends UserUpdateUserBaseInfo> clazz = targetUserBaseInfo.getClass();
Field[] fields = clazz.getDeclaredFields();
List<UpdateDetail> resList = new ArrayList<>();
for (Field field : fields) {
ReflectionUtils.makeAccessible(field);
Object targetValue = ReflectionUtils.getField(field, targetUserBaseInfo);
String targetString = "";
if (targetValue != null) {
targetString = String.valueOf(targetValue);
}
Object orgValue = ReflectionUtils.getField(field, orgUserBaseInfo);
String orgString = "";
if (orgValue != null) {
orgString = String.valueOf(orgValue);
}
if (!orgString.equals(targetString)) {
UpdateDetail UpdateDetail = new UpdateDetail();
UpdateDetail.setFieldName(field.getName());
if (targetString != null && !"".equals(targetString)) {
UpdateDetail.setFieldValue(targetString);
} else {
UpdateDetail.setFieldValue("");
}
UpdateDetail.setCreateTime(new Date());
resList.add(UpdateDetail);
}
}
return resList;
}
审核业务逻辑:
通过反射对数据进行更新
@Override
public void verify(VerifyVo verifyVo) {
//更新审核记录
Long recordId = verifyVo.getRecordId();
UpdateDetail UpdateDetail = new UpdateDetail();
UpdateDetail.setId(recordId);
UpdateDetail.setVerifyUserName(SecurityUtils.getUserName());
UpdateDetail.setUpdateTime(new Date());
UpdateDetail.setVerifyDesc(verifyVo.getVerifyDesc());
UpdateDetail.setVerifyStatus(verifyVo.getVerifyStatus());
this.updateById(UpdateDetail);
//如果审核通过把修改内容更新到数据上
if ("1".equals(verifyVo.getVerifyStatus())) {
Map<String, String> map = getRecRecordMap(recordId);
//更新用户表
Cons cons = ConsMapper.selectById(lcConsRec.getConsId());
List<String> fileNameList = updateObjByMap(map, cons);
ConsMapper.updateById(cons);
//更新关联表
String linkNo = map.get("linkNo");
if (linkNo != null && !"".equals(linkNo)) {
customerManagerService.insertShuntCons(lcConsRec.getConsId(), linkNo);
}
//清空多余数据,关联关系
if (fileNameList.contains("linkNo")) {
ConsMapper.updateId(lcConsRec.getConsId());
ConsMapper.removeId(lcConsRec.getConsId());
}
//批量把指定字段变为null
if(!fileNameList.isEmpty()){
ConsMapper.updateId(lcConsRec.getConsId(), humpToUnderlineList(fileNameList));
}
} else {
//如果审核不通过,重新创建一条审核记录
UpdateDetail newUpdateDetail = new UpdateDetail();
newUpdateDetail.setProcessId(verifyVo.getProcessId());
newUpdateDetail.setConsId(lcConsRec.getConsId());
newUpdateDetail.setSubmitStatus("0");
newUpdateDetail.setVerifyStatus("0");
this.save(newUpdateDetail);
}
}
/**
* 通过字段名称-值的方式修改对象属性值
*
* @param map 段名称-值
* @param object 对象
*/
private List<String> updateObjByMap(Map<String, String> map, Object object) {
Class<?> clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();
List<String> fieldNameList = new ArrayList<>();
for (Field field : fields) {
ReflectionUtils.makeAccessible(field);
String fieldName = field.getName();
String value = map.get(fieldName);
if(StringUtils.isEmpty(value)){
if (value != null) {
fieldNameList.add(fieldName);
}
continue;
}
String name = field.getType().getName();
if ("java.lang.Double".equals(name)) {
ReflectionUtils.setField(field, object, Double.valueOf(value));
} else if ("java.lang.Integer".equals(name)) {
ReflectionUtils.setField(field, object, Integer.valueOf(value));
} else {
ReflectionUtils.setField(field, object, value);
}
}
return fieldNameList;
}