Browse Source

对比 变更前后的项目字段

tags/24080901
PoffyZhang 1 year ago
parent
commit
8356bc0179
6 changed files with 310 additions and 8 deletions
  1. +22
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/compare/Compare.java
  2. +47
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/compare/CompareNode.java
  3. +181
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/compare/CompareUtils.java
  4. +53
    -8
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/manage/ProjectLibManage.java
  5. +2
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java
  6. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/vo/ProcessProgressDetailVo.java

+ 22
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/compare/Compare.java View File

@@ -0,0 +1,22 @@
package com.ningdatech.pmapi.common.compare;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 字段标记注解
*
* @author zpf
* @since 2023/07/21
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Compare {
/**
* 字段名称
*/
String value();
}

+ 47
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/compare/CompareNode.java View File

@@ -0,0 +1,47 @@
package com.ningdatech.pmapi.common.compare;
/**
* @author zpf
* @since 2023/07/21
*/
public class CompareNode {
/**
* 字段
*/
private String fieldKey;
/**
* 字段值
*/
private Object fieldValue;
/**
* 字段名称
*/
private String fieldName;
public String getFieldKey() {
return fieldKey;
}
public void setFieldKey(String fieldKey) {
this.fieldKey = fieldKey;
}
public Object getFieldValue() {
return fieldValue;
}
public void setFieldValue(Object fieldValue) {
this.fieldValue = fieldValue;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}

+ 181
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/compare/CompareUtils.java View File

@@ -0,0 +1,181 @@
package com.ningdatech.pmapi.common.compare;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.Field;
import java.util.*;
/**
* 使用须知: <br>
* (1)该工具类主要用于两个同类对象的属性值比较; <br>
* (2)使用本工具类前,请将对应的类属性上打上 @Compare("xxx") 注解,其中xxx为字段的表达名称;<br>
* (3)为了比较灵活,只有打了该注解才会进行比较,不打的字段则不会进行比较 <br>
* (4)比较后,只会返回有变化的字段,无变化的字符则不返回 <br>
*
* @author zpf
* @since 2023/07/21
*/
public class CompareUtils<T> {
private static final String COMMA = ",";
/**
* 属性比较
*
* @param source 源数据对象
* @param target 目标数据对象
* @return 对应属性值的比较变化
*/
public String compare(T source, T target) {
return compare(source, target, null);
}
/**
* 属性比较
*
* @param source 源数据对象
* @param target 目标数据对象
* @param ignoreCompareFields 忽略比较的字段
* @return 对应属性值的比较变化
*/
public String compare(T source, T target, List<String> ignoreCompareFields) {
if (Objects.isNull(source) && Objects.isNull(target)) {
return "";
}
Map<String, CompareNode> sourceMap = this.getFiledValueMap(source);
Map<String, CompareNode> targetMap = this.getFiledValueMap(target);
if (sourceMap.isEmpty() && targetMap.isEmpty()) {
return "";
}
// 如果源数据为空,则只显示目标数据,不显示属性变化情况
if (sourceMap.isEmpty()) {
return doEmpty(targetMap, ignoreCompareFields);
}
// 如果源数据为空,则显示属性变化情况
String s = doCompare(sourceMap, targetMap, ignoreCompareFields);
if (!s.endsWith(COMMA)) {
return s;
}
return s.substring(0, s.length() - 1);
}

public JSONObject compareToJson(T source, T target, List<String> ignoreCompareFields) {
JSONObject res = new JSONObject();
if (Objects.isNull(source) && Objects.isNull(target)) {
return res;
}
Map<String, CompareNode> sourceMap = this.getFiledValueMap(source);
Map<String, CompareNode> targetMap = this.getFiledValueMap(target);
if (sourceMap.isEmpty() && targetMap.isEmpty()) {
return res;
}
// 如果源数据为空,则只显示目标数据,不显示属性变化情况
if (sourceMap.isEmpty()) {
return res;
}

return doCompareJson(sourceMap, targetMap, ignoreCompareFields);
}
private String doEmpty(Map<String, CompareNode> targetMap, List<String> ignoreCompareFields) {
StringBuilder sb = new StringBuilder();
Collection<CompareNode> values = targetMap.values();
int size = values.size();
int current = 0;
for (CompareNode node : values) {
current++;
Object o = Optional.ofNullable(node.getFieldValue()).orElse("");
if (Objects.nonNull(ignoreCompareFields) && ignoreCompareFields.contains(node.getFieldKey())) {
continue;
}
if (o.toString().length() > 0) {
sb.append("[" + node.getFieldName() + ":" + o + "]");
if (current < size) {
sb.append(COMMA);
}
}
}
return sb.toString();
}
private String doCompare(Map<String, CompareNode> sourceMap, Map<String, CompareNode> targetMap, List<String> ignoreCompareFields) {
StringBuilder sb = new StringBuilder();
Set<String> keys = sourceMap.keySet();
int size = keys.size();
int current = 0;
for (String key : keys) {
current++;
CompareNode sn = sourceMap.get(key);
CompareNode tn = targetMap.get(key);
if (Objects.nonNull(ignoreCompareFields) && ignoreCompareFields.contains(sn.getFieldKey())) {
continue;
}
String sv = Optional.ofNullable(sn.getFieldValue()).orElse("").toString();
String tv = Optional.ofNullable(tn.getFieldValue()).orElse("").toString();
// 只有两者属性值不一致时, 才显示变化情况
if (!sv.equals(tv)) {
sb.append(String.format("[%s:%s -> %s]", sn.getFieldName(), sv, tv));
if (current < size) {
sb.append(COMMA);
}
}
}
return sb.toString();
}

private JSONObject doCompareJson(Map<String, CompareNode> sourceMap, Map<String, CompareNode> targetMap, List<String> ignoreCompareFields) {
JSONObject res = new JSONObject();
Set<String> keys = sourceMap.keySet();
int size = keys.size();
int current = 0;
for (String key : keys) {
current++;
CompareNode sn = sourceMap.get(key);
CompareNode tn = targetMap.get(key);
if (Objects.nonNull(ignoreCompareFields) && ignoreCompareFields.contains(sn.getFieldKey())) {
continue;
}
String sv = Optional.ofNullable(sn.getFieldValue()).orElse("").toString();
String tv = Optional.ofNullable(tn.getFieldValue()).orElse("").toString();
// 只有两者属性值不一致时, 才显示变化情况
if (!sv.equals(tv)) {
JSONObject valueChange = new JSONObject();
valueChange.put("old",sv);
valueChange.put("new",tv);
res.put(sn.getFieldName(),valueChange);
}
}
return res;
}
private Map<String, CompareNode> getFiledValueMap(T t) {
if (Objects.isNull(t)) {
return Collections.emptyMap();
}
Field[] fields = t.getClass().getDeclaredFields();
if (Objects.isNull(fields) || fields.length == 0) {
return Collections.emptyMap();
}
Map<String, CompareNode> map = new LinkedHashMap();
for (Field field : fields) {
Compare compareAnnotation = field.getAnnotation(Compare.class);
if (Objects.isNull(compareAnnotation)) {
continue;
}
field.setAccessible(true);
try {
String fieldKey = field.getName();
CompareNode node = new CompareNode();
node.setFieldKey(fieldKey);
node.setFieldValue(field.get(t));
node.setFieldName(compareAnnotation.value());
map.put(field.getName(), node);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
return map;
}
}

+ 53
- 8
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/manage/ProjectLibManage.java View File

@@ -14,6 +14,7 @@ import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.file.entity.File;
import com.ningdatech.file.service.FileService;
import com.ningdatech.pmapi.common.compare.CompareUtils;
import com.ningdatech.pmapi.common.constant.BizConst;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.constant.RegionConst;
@@ -1121,6 +1122,35 @@ public class ProjectLibManage {
}

/**
* 判断 当前项目是不是被驳回 或者 退回过
* @param projectId
* @return
*/
public Boolean isChangeRecord(Long projectId) {
//1.先判断下 项目存不存在
Project project = projectService.getById(projectId);
if(Objects.isNull(project)){
return Boolean.FALSE;
}

//2.要判断 项目在当前状态 有没有被驳回和退回过
//当前项目状态流程的 实例 看看是不是有2个以上 有2个说明 有退回 驳回
List<ProjectInst> pis = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class)
.eq(ProjectInst::getProjectId, projectId)
.orderByDesc(ProjectInst::getInstType)
.last("limit 2"));
if(CollUtil.isEmpty(pis)){
return Boolean.FALSE;
}
if( pis.size() < 2 ||
!pis.get(0).getInstType().equals(pis.get(1).getInstType())) {
return Boolean.FALSE;
}

return Boolean.TRUE;
}

/**
* 查看 项目的 变更记录(驳回 重新发起的 和上个版本的变更字段)
* @param projectId
* @return
@@ -1132,20 +1162,35 @@ public class ProjectLibManage {
Project project = projectService.getById(projectId);
VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在");


//2.要判断 项目在当前状态 有没有被驳回和退回过
//当前项目状态流程的 实例 看看是不是有2个以上 有2个说明 有退回 驳回
List<ProjectInst> pis = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class)
.eq(ProjectInst::getProjectId, projectId)
.orderByDesc(ProjectInst::getInstType)
.last("limit 2"));
VUtils.isTrue(CollUtil.isEmpty(pis)).throwMessage("该项目没有审批流");
VUtils.isTrue( pis.size() < 2 ||
!pis.get(0).getInstType().equals(pis.get(1).getInstType()))
.throwMessage("该项目在当前流程没有被驳回 撤回过");
Boolean isChangeRecord = isChangeRecord(projectId);
if(!isChangeRecord){
return res;
}

//3. 去对比 当前版本和上个版本 的字段对比
String projectCode = project.getProjectCode();
List<Project> twoVersions = projectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getProjectCode, projectCode)
.orderByDesc(Project::getVersion)
.last("limit 2"));
if(CollUtil.isEmpty(twoVersions) || twoVersions.size() < 2){
return res;
}

return checkTwoProjectChanges(res,twoVersions);
}

/**
* 列出 2个版本项目的 不同字段
* @param res
* @param twoVersions
* @return
*/
private JSONObject checkTwoProjectChanges(JSONObject res, List<Project> twoVersions) {
res = new CompareUtils<Project>().compareToJson(twoVersions.get(0), twoVersions.get(1),null);
return res;
}
}

+ 2
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java View File

@@ -563,6 +563,8 @@ public class TodoCenterManage {
res.setCanWithdraw(withDrawHandle.checkCanWithdraw(instanceId,progressInstanceDetail,request.getTaskId()));
res.setIsHighLine(isHighLine);
passHandle.checkCanPassOrSeal(request.getInstanceId(),request.getTaskId(),employeeCode,res);
//是不是被 驳回|退回
res.setIsChange(projectLibManage.isChangeRecord(projectId));
return res;
}



+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/vo/ProcessProgressDetailVo.java View File

@@ -58,4 +58,9 @@ public class ProcessProgressDetailVo {
* 当前审批人 是不是流程配置里的 上级条线主管
*/
private Boolean isHighLine = Boolean.FALSE;

/**
* 当前项目 是不是被 驳回|退回过
*/
private Boolean isChange = Boolean.FALSE;
}

Loading…
Cancel
Save