@@ -1,6 +1,6 @@ | |||
package com.hz.pm.api.projectdeclared.model.dto; | |||
import com.hz.pm.api.projectdeclared.utils.BeanDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectDetailDiffUtil.FieldDiff; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
@@ -151,7 +151,7 @@ public class EditPurchaseDTO { | |||
private LocalDate purchaseDate; | |||
@ApiModelProperty("是否发布信创云图") | |||
public Boolean publishMhNotice; | |||
private Boolean publishMhNotice; | |||
} |
@@ -1,6 +1,7 @@ | |||
package com.hz.pm.api.projectdeclared.model.dto; | |||
import com.hz.pm.api.projectdeclared.utils.BeanDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectdeclared.model.vo.PreInsAcceptancePersonVO; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectDetailDiffUtil.FieldDiff; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
@@ -23,12 +24,16 @@ public class EditPurchaseDetailDTO { | |||
public static final String FIELD_OPERATION = "operation"; | |||
public static final String FIELD_FIRST_INSPECTED_PERSONS = "firstInspectedPersons"; | |||
public static final String FIELD_PURCHASE_DIFFS = "purchaseDiffs"; | |||
public static final String FIELD_CONTRACT_DIFFS = "contractDiffs"; | |||
public static final String FIELD_OPERATION_DIFFS = "operationDiffs"; | |||
public static final String FIELD_FIRST_INSPECTED_PERSONS_DIFF = "firstInspectedPersonsDiff"; | |||
//================================================================================================================== | |||
@ApiModelProperty("采购信息") | |||
@@ -46,4 +51,10 @@ public class EditPurchaseDetailDTO { | |||
private List<FieldDiff> operationDiffs; | |||
@ApiModelProperty("初验人员") | |||
private List<PreInsAcceptancePersonVO> firstInspectedPersons; | |||
private FieldDiff firstInspectedPersonsDiff; | |||
} |
@@ -1,8 +1,6 @@ | |||
package com.hz.pm.api.projectdeclared.model.entity; | |||
import com.baomidou.mybatisplus.annotation.IdType; | |||
import com.baomidou.mybatisplus.annotation.TableId; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.baomidou.mybatisplus.annotation.*; | |||
import io.swagger.annotations.ApiModel; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
@@ -33,9 +31,11 @@ public class PreInsAcceptancePerson { | |||
private String updateBy; | |||
@ApiModelProperty("创建时间") | |||
@TableField(fill = FieldFill.INSERT) | |||
private LocalDateTime createOn; | |||
@ApiModelProperty("修改时间") | |||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||
private LocalDateTime updateOn; | |||
@ApiModelProperty("项目ID") | |||
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
import java.time.LocalDateTime; | |||
import java.util.Objects; | |||
/** | |||
* <p> | |||
@@ -29,4 +30,23 @@ public class PreInsAcceptancePersonVO { | |||
@ApiModelProperty("单位") | |||
private String unit; | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
return true; | |||
} | |||
if (o == null || getClass() != o.getClass()) { | |||
return false; | |||
} | |||
PreInsAcceptancePersonVO that = (PreInsAcceptancePersonVO) o; | |||
return Objects.equals(id, that.id) | |||
&& Objects.equals(projectId, that.projectId) | |||
&& Objects.equals(personName, that.personName) | |||
&& Objects.equals(unit, that.unit); | |||
} | |||
@Override | |||
public int hashCode() { | |||
return Objects.hash(id, projectId, personName, unit); | |||
} | |||
} |
@@ -0,0 +1,98 @@ | |||
package com.hz.pm.api.projectdeclared.utils; | |||
import java.time.LocalDate; | |||
import java.time.LocalDateTime; | |||
import java.time.LocalTime; | |||
import java.time.ZoneId; | |||
import java.time.format.DateTimeFormatter; | |||
import java.util.Date; | |||
/** | |||
* <p> | |||
* DateFormatUtil | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 12:59 2024/8/9 | |||
*/ | |||
public class DateFormatUtil { | |||
private DateFormatUtil() { | |||
} | |||
/** | |||
* 判断对象是否为日期类型,并进行格式化。 | |||
* | |||
* @param obj 要判断的对象 | |||
* @return 如果是日期类型则返回格式化的字符串,否则返回 null | |||
*/ | |||
public static String format(Object obj) { | |||
// 检查对象是否为日期类型 | |||
if (isDateType(obj)) { | |||
// 根据日期类型选择合适的 DateTimeFormatter | |||
DateTimeFormatter formatter = getDateTimeFormatter(obj); | |||
if (formatter != null) { | |||
// 格式化日期 | |||
return format(obj, formatter); | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* 判断对象是否为日期类型。 | |||
* | |||
* @param obj 要判断的对象 | |||
* @return 如果是日期类型返回 true,否则返回 false | |||
*/ | |||
public static boolean isDateType(Object obj) { | |||
if (obj != null) { | |||
Class<?> clazz = obj.getClass(); | |||
return clazz.isAssignableFrom(LocalDate.class) | |||
|| clazz.isAssignableFrom(LocalDateTime.class) | |||
|| clazz.isAssignableFrom(LocalTime.class) | |||
|| clazz.isAssignableFrom(Date.class); | |||
} | |||
return false; | |||
} | |||
/** | |||
* 根据日期类型获取对应的 DateTimeFormatter。 | |||
* | |||
* @param obj 日期对象 | |||
* @return 对应的 DateTimeFormatter | |||
*/ | |||
private static DateTimeFormatter getDateTimeFormatter(Object obj) { | |||
if (obj instanceof LocalDate) { | |||
return DateTimeFormatter.ofPattern("yyyy-MM-dd"); | |||
} else if (obj instanceof LocalDateTime) { | |||
return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||
} else if (obj instanceof LocalTime) { | |||
return DateTimeFormatter.ofPattern("HH:mm:ss"); | |||
} else if (obj instanceof Date) { | |||
return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |||
} | |||
return null; | |||
} | |||
/** | |||
* 格式化日期对象为字符串。 | |||
* | |||
* @param obj 日期对象 | |||
* @param formatter 日期格式器 | |||
* @return 格式化的字符串 | |||
*/ | |||
private static String format(Object obj, DateTimeFormatter formatter) { | |||
if (obj instanceof LocalDate) { | |||
return ((LocalDate) obj).format(formatter); | |||
} else if (obj instanceof LocalDateTime) { | |||
return ((LocalDateTime) obj).format(formatter); | |||
} else if (obj instanceof LocalTime) { | |||
return ((LocalTime) obj).format(formatter); | |||
} else if (obj instanceof Date) { | |||
return LocalDateTime.ofInstant(((Date) obj).toInstant(), ZoneId.systemDefault()).format(formatter); | |||
} | |||
return null; | |||
} | |||
} |
@@ -18,9 +18,9 @@ import java.util.*; | |||
* @author WendyYang | |||
* @since 10:27 2024/8/6 | |||
*/ | |||
public final class BeanDiffUtil { | |||
public final class ProjectDetailDiffUtil { | |||
private BeanDiffUtil() { | |||
private ProjectDetailDiffUtil() { | |||
} | |||
@Data | |||
@@ -73,8 +73,8 @@ public final class BeanDiffUtil { | |||
result.add(FieldDiff.builder() | |||
.fieldName(key) | |||
.fieldType((oldObj == null ? newVal.getClass() : oldVal.getClass()).getTypeName()) | |||
.oldValue(oldVal) | |||
.newValue(newVal) | |||
.oldValue(formatDate(oldVal)) | |||
.newValue(formatDate(newVal)) | |||
.build()); | |||
} | |||
@@ -89,8 +89,8 @@ public final class BeanDiffUtil { | |||
continue; | |||
} | |||
Class<?> clazz = oldVal == null ? newVal.getClass() : oldVal.getClass(); | |||
oldVal = MapUtil.get(oldObjMap, key, clazz); | |||
newVal = MapUtil.get(newObjMap, key, clazz); | |||
oldVal = formatDate(MapUtil.get(oldObjMap, key, clazz)); | |||
newVal = formatDate(MapUtil.get(newObjMap, key, clazz)); | |||
// 如果是嵌套对象,则递归比较 | |||
if (!BeanUtil.isBean(clazz) && ObjUtil.notEqual(oldVal, newVal)) { | |||
result.add(FieldDiff.builder() | |||
@@ -104,4 +104,11 @@ public final class BeanDiffUtil { | |||
return result; | |||
} | |||
private static Object formatDate(Object date) { | |||
if (DateFormatUtil.isDateType(date)) { | |||
return DateFormatUtil.format(date); | |||
} | |||
return date; | |||
} | |||
} |
@@ -85,6 +85,14 @@ public class ProjectStoppedChangeController { | |||
return projectChangeManage.changeDetail(id); | |||
} | |||
@GetMapping("/change/detail/{projectId}/{instCode}") | |||
@ApiOperation("项目变更详情") | |||
@WebLog("项目变更详情") | |||
public ProjectChangeDetailVO changeDetail(@PathVariable("projectId") Long projectId, | |||
@PathVariable("instCode") String instCode) { | |||
return projectChangeManage.changeDetail(projectId, instCode); | |||
} | |||
@GetMapping("/change/options") | |||
@ApiOperation("项目变更下拉筛选") | |||
@WebLog("项目变更下拉筛选") | |||
@@ -16,15 +16,13 @@ import com.hz.pm.api.projectdeclared.entity.ProjectChangeHistory; | |||
import com.hz.pm.api.projectdeclared.model.dto.*; | |||
import com.hz.pm.api.projectdeclared.model.entity.Contract; | |||
import com.hz.pm.api.projectdeclared.model.entity.Operation; | |||
import com.hz.pm.api.projectdeclared.model.entity.PreInsAcceptancePerson; | |||
import com.hz.pm.api.projectdeclared.model.entity.Purchase; | |||
import com.hz.pm.api.projectdeclared.service.IContractService; | |||
import com.hz.pm.api.projectdeclared.service.IOperationService; | |||
import com.hz.pm.api.projectdeclared.service.IProjectChangeHistoryService; | |||
import com.hz.pm.api.projectdeclared.service.IPurchaseService; | |||
import com.hz.pm.api.projectdeclared.utils.BeanDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectdeclared.model.vo.PreInsAcceptancePersonVO; | |||
import com.hz.pm.api.projectdeclared.service.*; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectDetailDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange; | |||
import com.hz.pm.api.projectlib.manage.ProjectLibManage; | |||
import com.hz.pm.api.projectdeclared.model.dto.EditProjectDTO; | |||
import com.hz.pm.api.projectlib.model.entity.Project; | |||
import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange; | |||
import com.hz.pm.api.projectlib.model.enumeration.status.*; | |||
@@ -56,6 +54,7 @@ public class ProjectChangeStopHelper { | |||
private final IProjectChangeHistoryService projectChangeHistoryService; | |||
private final IPurchaseStatusChangeService purchaseStatusChangeService; | |||
private final IProjectStatusChangeService projectStatusChangeService; | |||
private final IPreInsAcceptancePersonService preInsAcceptancePersonService; | |||
private final IPurchaseService purchaseService; | |||
private final IOperationService operationService; | |||
private final IContractService contractService; | |||
@@ -242,6 +241,23 @@ public class ProjectChangeStopHelper { | |||
List<EditPurchaseDetailDTO> purchases = projectEdit.getPurchases(); | |||
if (CollUtil.isNotEmpty(purchases)) { | |||
for (EditPurchaseDetailDTO purchaseEdit : purchases) { | |||
// 初验人员保存 | |||
if (purchaseEdit.getFirstInspectedPersonsDiff() == null) { | |||
Long purchaseId = purchaseEdit.getPurchase().getId(); | |||
preInsAcceptancePersonService.removeByBidId(purchaseId); | |||
List<PreInsAcceptancePersonVO> firstInspectedPersons = purchaseEdit.getFirstInspectedPersons(); | |||
if (CollUtil.isNotEmpty(firstInspectedPersons)) { | |||
List<PreInsAcceptancePerson> persons = firstInspectedPersons.stream().map(d -> { | |||
PreInsAcceptancePerson person = new PreInsAcceptancePerson(); | |||
person.setPersonName(d.getPersonName()); | |||
person.setUnit(d.getUnit()); | |||
person.setBidId(purchaseId); | |||
person.setProjectId(d.getProjectId()); | |||
return person; | |||
}).collect(Collectors.toList()); | |||
preInsAcceptancePersonService.saveBatch(persons); | |||
} | |||
} | |||
modifyPurchase(purchaseEdit); | |||
modifyContract(purchaseEdit); | |||
modifyOperation(purchaseEdit); | |||
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.collection.CollUtil; | |||
import cn.hutool.json.JSONObject; | |||
import cn.hutool.json.JSONUtil; | |||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
@@ -12,13 +13,10 @@ import com.hz.pm.api.external.model.enumeration.MhUnitStripEnum; | |||
import com.hz.pm.api.projectdeclared.entity.ProjectChangeHistory; | |||
import com.hz.pm.api.projectdeclared.manage.DeclaredProjectHelper; | |||
import com.hz.pm.api.projectdeclared.model.dto.*; | |||
import com.hz.pm.api.projectdeclared.model.vo.ContractVO; | |||
import com.hz.pm.api.projectdeclared.model.vo.OperationVO; | |||
import com.hz.pm.api.projectdeclared.model.vo.PurchaseFullInfoVO; | |||
import com.hz.pm.api.projectdeclared.model.vo.PurchaseVO; | |||
import com.hz.pm.api.projectdeclared.model.vo.*; | |||
import com.hz.pm.api.projectdeclared.service.IProjectChangeHistoryService; | |||
import com.hz.pm.api.projectdeclared.utils.BeanDiffUtil; | |||
import com.hz.pm.api.projectdeclared.utils.BeanDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectDetailDiffUtil; | |||
import com.hz.pm.api.projectdeclared.utils.ProjectDetailDiffUtil.FieldDiff; | |||
import com.hz.pm.api.projectlib.helper.ProjectChangeStopHelper; | |||
import com.hz.pm.api.projectlib.helper.ProjectManageUtil; | |||
import com.hz.pm.api.projectlib.model.dto.GovSystemReplaceInfoDTO; | |||
@@ -92,13 +90,13 @@ public class ProjectChangeManage { | |||
} | |||
ProjectDetailVO projDetailOld = projectLibManage.getProjectDetail(project); | |||
List<FieldDiff> projDiffs = BeanDiffUtil.diff(projDetailOld, projJsonObj, true, | |||
List<FieldDiff> projDiffs = ProjectDetailDiffUtil.diff(projDetailOld, projJsonObj, true, | |||
EditProjectDTO.SYSTEM_REPLACE_INFOS, "id", "projectCode"); | |||
List<GovSystemReplaceInfoDTO> systemReplaceInfos = reqProj.getSystemReplaceInfos(); | |||
List<GovSystemReplaceInfoDTO> systemReplaceInfosOld = projDetailOld.getSystemReplaceInfos(); | |||
if (!CollUtil.isEqualList(systemReplaceInfos, systemReplaceInfosOld)) { | |||
projDiffs.add(FieldDiff.builder() | |||
.fieldName("systemReplaceInfos") | |||
.fieldName(EditProjectDTO.SYSTEM_REPLACE_INFOS) | |||
.fieldType(List.class.getTypeName()) | |||
.oldValue(systemReplaceInfosOld) | |||
.newValue(systemReplaceInfos) | |||
@@ -115,15 +113,27 @@ public class ProjectChangeManage { | |||
PurchaseVO purchase = purchaseDetail.getPurchase(); | |||
ContractVO contract = purchaseDetail.getConstruction(); | |||
OperationVO operation = purchaseDetail.getOperation(); | |||
List<PreInsAcceptancePersonVO> firstInspectedPersons = purchaseDetail.getFirstInspectedPersons(); | |||
JSONObject reqPurchaseDetail = reqPurchaseMap.get(purchase.getId()); | |||
JSONObject reqPurchase = reqPurchaseDetail.getJSONObject(EditPurchaseDetailDTO.FIELD_PURCHASE); | |||
JSONObject reqOperation = reqPurchaseDetail.getJSONObject(EditPurchaseDetailDTO.FIELD_OPERATION); | |||
JSONObject reqContract = reqPurchaseDetail.getJSONObject(EditPurchaseDetailDTO.FIELD_CONTRACT); | |||
List<FieldDiff> purchaseDiffs = BeanDiffUtil.diff(purchase, reqPurchase, true, "id"); | |||
List<FieldDiff> operationDiffs = BeanDiffUtil.diff(operation, reqOperation, true, "id"); | |||
List<FieldDiff> contractDiffs = BeanDiffUtil.diff(contract, reqContract, true, "id"); | |||
List<PreInsAcceptancePersonVO> reqFirstInspectedPersons = reqPurchaseDetail.getBeanList(EditPurchaseDetailDTO.FIELD_FIRST_INSPECTED_PERSONS, PreInsAcceptancePersonVO.class); | |||
if (!CollUtil.isEqualList(firstInspectedPersons, reqFirstInspectedPersons)) { | |||
reqPurchaseDetail.set(EditPurchaseDetailDTO.FIELD_FIRST_INSPECTED_PERSONS_DIFF, | |||
FieldDiff.builder() | |||
.fieldName(EditPurchaseDetailDTO.FIELD_FIRST_INSPECTED_PERSONS) | |||
.fieldType(List.class.getTypeName()) | |||
.oldValue(firstInspectedPersons) | |||
.newValue(reqFirstInspectedPersons) | |||
.build()); | |||
} | |||
List<FieldDiff> purchaseDiffs = ProjectDetailDiffUtil.diff(purchase, reqPurchase, true, "id"); | |||
List<FieldDiff> operationDiffs = ProjectDetailDiffUtil.diff(operation, reqOperation, true, "id"); | |||
List<FieldDiff> contractDiffs = ProjectDetailDiffUtil.diff(contract, reqContract, true, "id"); | |||
reqPurchaseDetail.set(EditPurchaseDetailDTO.FIELD_PURCHASE_DIFFS, purchaseDiffs); | |||
reqPurchaseDetail.set(EditPurchaseDetailDTO.FIELD_CONTRACT_DIFFS, contractDiffs); | |||
reqPurchaseDetail.set(EditPurchaseDetailDTO.FIELD_OPERATION_DIFFS, operationDiffs); | |||
@@ -151,7 +161,6 @@ public class ProjectChangeManage { | |||
projectChangeStopHelper.changeProjectPurchaseStatus(project, CHANGE_APPLY_SUBMIT); | |||
projectEditDetail.getConfig().setIgnoreNullValue(false); | |||
// 保存变更历史 | |||
ProjectChangeHistory projectChangeHistory = new ProjectChangeHistory(); | |||
projectChangeHistory.setChangeContent(projectEditDetail.toString()); | |||
@@ -197,6 +206,21 @@ public class ProjectChangeManage { | |||
return result; | |||
} | |||
public ProjectChangeDetailVO changeDetail(Long projectId,String instCode) { | |||
Wrapper<ProjectChangeHistory> query = Wrappers.lambdaQuery(ProjectChangeHistory.class) | |||
.eq(ProjectChangeHistory::getProjectId, projectId) | |||
.eq(ProjectChangeHistory::getInstCode, instCode); | |||
ProjectChangeHistory changeHistory = projectChangeHistoryService.getOne(query); | |||
if (changeHistory == null) { | |||
return null; | |||
} | |||
ProjectChangeDetailVO result = new ProjectChangeDetailVO(); | |||
result.setProjectEditDetail(JSONUtil.toBean(changeHistory.getChangeContent(), EditProjectDetailDTO.class)); | |||
result.setChangeReason(changeHistory.getChangeReason()); | |||
result.setCreateOn(changeHistory.getCreateOn()); | |||
return result; | |||
} | |||
public List<ProjectLibListItemVO> options() { | |||
LambdaQueryWrapper<Project> query = Wrappers.lambdaQuery(Project.class) | |||
.select(Project::getId, Project::getProjectCode, Project::getProjectName) | |||