feat(项目管理产品需求重构): 完善产品中的用户需求功能开发

1. 增加用户需求和操作记录的关联查询操作,查询需求最新的评审情况
2. 查询用户需求列表时返回评审人、评审时间和评审意见
3. 修正部分评审记录异常的问题

Signed-off-by: OTTO <731554297@qq.com>
This commit is contained in:
OTTO 2024-12-03 14:44:04 +08:00
parent 05a7dab7bd
commit bccc9b8e12
6 changed files with 92 additions and 20 deletions

View File

@ -151,6 +151,13 @@ public class PmsProductRequirement extends BaseEntity
@ApiModelProperty(value = "需求标识")
private String identifier;
@ApiModelProperty(value = "评审时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date reviewTime;
@ApiModelProperty(value = "评审内容")
private String reviewContent;
public PmsProductRequirementDataVo toPmsProductRequirementDataVo(){
PmsProductRequirementDataVo target = new PmsProductRequirementDataVo();
BeanUtils.copyProperties(this, target);

View File

@ -12,7 +12,7 @@ public enum ProductReqOperationType {
CONTENT_MODIFY("contentModify", "内容修改"),
REVIEW_USER_REQ("reviewUserReq", "用户需求评审"),
ACTIVE_PLAN("activePlan", "纳入计划"),
REVIEW_REQ_SPECS("reviewUserReq", "需求规格评审");
REVIEW_REQ_SPECS("reviewReqSpecs", "需求规格评审");
private final String key;
private final String name;

View File

@ -1,5 +1,6 @@
package com.microservices.pms.product.domain.vo;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.pms.product.domain.PmsProductReqOperationRecord;
import com.microservices.pms.product.domain.enums.ProductReqOperationType;
import io.swagger.annotations.ApiModel;
@ -31,29 +32,36 @@ public class ProductReqReviewVo {
@NotNull
private Date reviewTime;
@ApiModelProperty(value = "评审人", required = true)
@NotNull
private String reviewUser;
@ApiModelProperty(value = "评审意见", required = true)
@NotNull
private String reviewContent;
public PmsProductReqOperationRecord toUserReqRecord(String operator) {
PmsProductReqOperationRecord record = new PmsProductReqOperationRecord();
record.setProductRequirementId(id);
PmsProductReqOperationRecord record = toRecord(operator);
record.setType(ProductReqOperationType.REVIEW_USER_REQ.getKey());
record.setOperation(reviewStatus);
record.setOperator(operator);
record.setOperatingTime(reviewTime);
record.setContent(reviewContent);
return record;
}
public PmsProductReqOperationRecord toReqSpecsRecord(String operator) {
PmsProductReqOperationRecord record = toRecord(operator);
record.setType(ProductReqOperationType.REVIEW_REQ_SPECS.getKey());
return record;
}
private PmsProductReqOperationRecord toRecord(String operator) {
PmsProductReqOperationRecord record = new PmsProductReqOperationRecord();
record.setProductRequirementId(id);
record.setType(ProductReqOperationType.REVIEW_REQ_SPECS.getKey());
record.setOperation(reviewStatus);
record.setOperator(operator);
record.setOperatingTime(reviewTime);
record.setContent(reviewContent);
JSONObject contentJson = new JSONObject();
contentJson.put("reviewUser", reviewUser);
contentJson.put("reviewContent", reviewContent);
record.setContent(contentJson.toJSONString());
return record;
}
}

View File

@ -40,6 +40,16 @@ public class ProductUserReqDataVo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty(value = "评审时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date reviewTime;
@ApiModelProperty(value = "评审人")
private String reviewUser;
@ApiModelProperty(value = "评审意见")
private String reviewContent;
public ProductUserReqDetailVo toProductReqUserDetailVo() {
ProductUserReqDetailVo target = new ProductUserReqDetailVo();
BeanUtils.copyProperties(this, target);

View File

@ -1,5 +1,6 @@
package com.microservices.pms.product.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.exception.NotFoundException;
@ -177,7 +178,12 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
ProductUserReqDataVo productUserReqDataVo = pmsProductRequirement.toProductUserReqDataVo();
// 设置状态
productUserReqDataVo.setStatus(ProductReqStatus.getTypeByKey(pmsProductRequirement.getStatus()));
if (StringUtils.isNotEmpty(pmsProductRequirement.getReviewContent())
&& JSON.isValid(pmsProductRequirement.getReviewContent())) {
JSONObject reviewContentJson = JSONObject.parseObject(pmsProductRequirement.getReviewContent());
productUserReqDataVo.setReviewUser(reviewContentJson.getString("reviewUser"));
productUserReqDataVo.setReviewContent(reviewContentJson.getString("reviewContent"));
}
return productUserReqDataVo;
}
@ -354,18 +360,18 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
if (!ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey().equals(userReq.getStatus())) {
throw new ServiceException("只有待审核状态的用户需求才能进行审核");
}
PmsProductReqOperationRecord pmsProductReqOperationRecord
= productReqReviewVo.toUserReqRecord(SecurityUtils.getUsername());
if (ProductReqReviewStatus.PASS.getKey().equals(productReqReviewVo.getReviewStatus())) {
userReq.setStatus(ProductReqStatus.REVIEWED_USER_REQ.getKey());
userReqToReqSpecs(userReq, pmsProductReqOperationRecord);
userReqToReqSpecs(userReq, productReqReviewVo.toUserReqRecord(SecurityUtils.getUsername()));
} else if (ProductReqReviewStatus.REJECTED.getKey().equals(productReqReviewVo.getReviewStatus())) {
userReq.setStatus(ProductReqStatus.REJECTED_USER_REQ.getKey());
} else {
throw new ServiceException("请选择正确的审核状态");
}
// 记录评审意见
pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(pmsProductReqOperationRecord);
pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
productReqReviewVo.toUserReqRecord(SecurityUtils.getUsername()));
return updateRequirement(userReq, userReq.getPmsProductIdentifier());
}
@ -378,8 +384,6 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
&& !ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
throw new ServiceException("只有待审核和变更中状态的需求规格才能进行审核");
}
PmsProductReqOperationRecord pmsProductReqOperationRecord
= productReqReviewVo.toReqSpecsRecord(SecurityUtils.getUsername());
if (ProductReqReviewStatus.PASS.getKey().equals(productReqReviewVo.getReviewStatus())) {
if (ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
PmsProductRequirement fromReqSpecs = selectPmsProductRequirementById(reqSpecs.getFromId(), true);
@ -403,8 +407,10 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
pmsJournalsService.updateJournalsIdByTypeAndOldId(
PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, reqSpecs.getId(), fromReqSpecs.getId());
// 原需规记录评审意见
pmsProductReqOperationRecord.setId(fromReqSpecs.getId());
pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(pmsProductReqOperationRecord);
PmsProductReqOperationRecord oldReqSpecsRecord
= productReqReviewVo.toReqSpecsRecord(SecurityUtils.getUsername());
oldReqSpecsRecord.setId(fromReqSpecs.getId());
pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(oldReqSpecsRecord);
} else {
reqSpecs.setStatus(ProductReqStatus.REJECTED_REQ_SPECS.getKey());
}
@ -412,6 +418,8 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
throw new ServiceException("请选择正确的审核状态");
}
// 记录评审意见
PmsProductReqOperationRecord pmsProductReqOperationRecord
= productReqReviewVo.toReqSpecsRecord(SecurityUtils.getUsername());
pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(pmsProductReqOperationRecord);
return updateRequirement(reqSpecs, reqSpecs.getPmsProductIdentifier());
}

View File

@ -38,7 +38,7 @@
select id,
title,
`index`,
status,
`status`,
priority_id,
pms_product_module_id,
pms_product_plan_id,
@ -65,6 +65,45 @@
from pms_product_requirement
</sql>
<sql id="selectUserReqAndRecord">
select ppr.id,
ppr.title,
ppr.`index`,
ppr.`status`,
ppr.priority_id,
ppr.pms_product_module_id,
ppr.pms_product_plan_id,
ppr.pms_product_identifier,
ppr.content,
ppr.tag_ids,
ppr.start_time,
ppr.end_time,
ppr.file_identifiers,
ppr.sort,
ppr.update_time,
ppr.update_by,
ppr.create_time,
ppr.create_by,
ppr.del_flag,
ppr.requirement_assignee_gitlink_ids,
ppr.pms_project_id,
ppr.from_id,
ppr.project_req_id,
ppr.type,
ppr.source_user,
ppr.source_company,
ppr.identifier,
record.reviewTime,
record.content as reviewContent
from pms_product_requirement as ppr
left join (select product_requirement_id, MAX(operating_time) as reviewTime, content
from pms_product_req_operation_record
where type = 'reviewUserReq'
group by product_requirement_id, content) as record
on record.product_requirement_id = ppr.id
</sql>
<select id="selectPmsProductRequirementList" parameterType="PmsProductRequirement"
resultMap="PmsProductRequirementResult">
/*keep orderby*/
@ -142,7 +181,7 @@
</select>
<select id="selectUserReqList" resultMap="PmsProductRequirementResult">
/*keep orderby*/
<include refid="selectPmsProductRequirementVo"/>
<include refid="selectUserReqAndRecord"/>
<where>
<if test="search != null and search != ''">and
(