From 604bf619815b820164546ba67ac51bb987c85b2d Mon Sep 17 00:00:00 2001 From: dk <1260500659@qq.com> Date: Sat, 9 May 2026 13:44:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E4=BA=A7=E5=93=81=E9=9C=80=E6=B1=82):=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=B5=8B=E8=AF=95=E5=90=8E=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../requirement/ProductRequirementRespVO.java | 24 +-- .../ProductRequirementSaveReqVO.java | 34 ++-- .../ProductRequirementSplitReqVO.java | 34 ++-- .../ProductRequirementUpdateReqVO.java | 34 ++-- .../product/ProductRequirementDO.java | 28 ++- .../ProductRequirementServiceImpl.java | 165 ++++++++++++++-- .../ProductRequirementServiceImplTest.java | 20 +- .../UserManagementRelationController.java | 23 +++ .../user/UserManagementRelationService.java | 8 + .../UserManagementRelationServiceImpl.java | 177 +++++++++--------- 10 files changed, 365 insertions(+), 182 deletions(-) diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementRespVO.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementRespVO.java index 46a32c9..80854e6 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementRespVO.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementRespVO.java @@ -16,19 +16,19 @@ public class ProductRequirementRespVO { @Schema(description = "需求ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; - @Schema(description = "父需求ID(0表示顶级需求)", example = "0") + @Schema(description = "父需求ID,0 表示顶级需求", example = "0") private Long parentId; @Schema(description = "所属模块ID", example = "1024") private Long moduleId; - @Schema(description = "是否需要评审(0不需要;1需要)", example = "0") + @Schema(description = "是否需要评审,0不需要,1需要", example = "0") private Integer reviewRequired; @Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理") private String title; - @Schema(description = "需求描述(富文本)", example = "
详细描述需求内容
") + @Schema(description = "需求描述,支持富文本", example = "详细描述需求内容
") private String description; @Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function") @@ -37,13 +37,13 @@ public class ProductRequirementRespVO { @Schema(description = "需求分类名称", example = "功能需求") private String categoryName; - @Schema(description = "来源类型(manual:手工新增, work_order:工单流转)", requiredMode = Schema.RequiredMode.REQUIRED, example = "manual") + @Schema(description = "需求来源类型,manual 表示手工新增,work_order 表示工单流转", requiredMode = Schema.RequiredMode.REQUIRED, example = "manual") private String sourceType; @Schema(description = "来源业务ID", example = "1024") private Long sourceBizId; - @Schema(description = "优先级(0低 1中 2高 3紧急)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "优先级,0低、1中、2高、3紧急", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer priority; @Schema(description = "优先级名称", example = "中") @@ -58,13 +58,16 @@ public class ProductRequirementRespVO { @Schema(description = "最近一次状态动作原因", example = "评审通过") private String lastStatusReason; - @Schema(description = "提出人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long proposerId; @Schema(description = "提出人用户姓名", example = "张三") private String proposerNickname; - @Schema(description = "当前处理人用户编号", example = "1024") + @Schema(description = "所需工时", example = "8") + private Double workHours; + + @Schema(description = "当前处理人用户ID", example = "1024") private Long currentHandlerUserId; @Schema(description = "当前处理人姓名", example = "李四") @@ -76,9 +79,6 @@ public class ProductRequirementRespVO { @Schema(description = "实现项目名称", example = "NPQS-10086") private String implementProjectName; - @Schema(description = "预期完成时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime completionDate; - @Schema(description = "排序值", example = "0") private Integer sort; @@ -88,10 +88,10 @@ public class ProductRequirementRespVO { @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime updateTime; - @Schema(description = "子需求列表(树形结构)") + @Schema(description = "子需求列表,树形结构") private List详细描述需求内容
") + @Schema(description = "需求描述,支持富文本", example = "详细描述需求内容
") private String description; @Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function") @NotBlank(message = "需求分类不能为空") - @Size(max = 64, message = "需求分类长度不能超过64个字符") + @Size(max = 64, message = "需求分类长度不能超过 64 个字符") private String category; - @Schema(description = "优先级(0低 1中 2高 3紧急)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "优先级,0低、1中、2高、3紧急", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "优先级不能为空") private Integer priority; - @Schema(description = "提出人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "提出人不能为空") private Long proposerId; - @Schema(description = "当前处理人用户编号", example = "1024") + @Schema(description = "提出人姓名", example = "张三") + private String proposerNickname; + + @Schema(description = "所需工时", example = "8") + @NotNull(message = "所需工时不能为空") + private Double workHours; + + @Schema(description = "当前处理人用户ID", example = "1024") private Long currentHandlerUserId; + @Schema(description = "当前处理人姓名", example = "李四") + private String currentHandlerUserNickname; + @Schema(description = "默认实现项目编号", example = "1024") private Long implementProjectId; - @Schema(description = "预期完成时间", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "预期完成时间不能为空") - private LocalDateTime completionDate; - - @Schema(description = "排序值(越小越靠前)", example = "0") + @Schema(description = "排序值,越小越靠前", example = "0") private Integer sort; } diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementSplitReqVO.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementSplitReqVO.java index bc975ae..cb88c9b 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementSplitReqVO.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementSplitReqVO.java @@ -6,8 +6,6 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; -import java.time.LocalDateTime; - /** * 管理后台 - 产品需求拆分 Request VO */ @@ -23,45 +21,51 @@ public class ProductRequirementSplitReqVO { @NotNull(message = "产品编号不能为空") private Long productId; - @Schema(description = "所属模块ID(为空时归入全部需求)", example = "1024") + @Schema(description = "所属模块ID,为空时归入全部需求模块", example = "1024") private Long moduleId; - @Schema(description = "是否需要评审(0不需要;1需要)", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @Schema(description = "是否需要评审,0不需要,1需要", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @NotNull(message = "是否需要评审不能为空") private Integer reviewRequired; @Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理") @NotBlank(message = "需求标题不能为空") - @Size(max = 200, message = "需求标题长度不能超过200个字符") + @Size(max = 200, message = "需求标题长度不能超过 200 个字符") private String title; - @Schema(description = "需求描述(富文本)", example = "详细描述需求内容
") + @Schema(description = "需求描述,支持富文本", example = "详细描述需求内容
") private String description; @Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function") @NotBlank(message = "需求分类不能为空") - @Size(max = 64, message = "需求分类长度不能超过64个字符") + @Size(max = 64, message = "需求分类长度不能超过 64 个字符") private String category; - @Schema(description = "优先级(0低 1中 2高 3紧急)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "优先级,0低、1中、2高、3紧急", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "优先级不能为空") private Integer priority; - @Schema(description = "提出人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "提出人不能为空") private Long proposerId; - @Schema(description = "当前处理人用户编号", example = "1024") + @Schema(description = "提出人姓名", example = "张三") + private String proposerNickname; + + @Schema(description = "所需工时", example = "8") + @NotNull(message = "所需工时不能为空") + private Double workHours; + + @Schema(description = "当前处理人用户ID", example = "1024") private Long currentHandlerUserId; + @Schema(description = "当前处理人姓名", example = "李四") + private String currentHandlerUserNickname; + @Schema(description = "默认实现项目编号", example = "1024") private Long implementProjectId; - @Schema(description = "预期完成时间", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "预期完成时间不能为空") - private LocalDateTime completionDate; - - @Schema(description = "排序值(越小越靠前)", example = "0") + @Schema(description = "排序值,越小越靠前", example = "0") private Integer sort; } diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementUpdateReqVO.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementUpdateReqVO.java index 49f5e27..1b7d7b8 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementUpdateReqVO.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/product/vo/requirement/ProductRequirementUpdateReqVO.java @@ -6,8 +6,6 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; -import java.time.LocalDateTime; - /** * 管理后台 - 产品需求编辑 Request VO */ @@ -23,45 +21,51 @@ public class ProductRequirementUpdateReqVO { @NotNull(message = "产品ID不能为空") private Long productId; - @Schema(description = "所属模块ID(为空时归入全部需求)", example = "1024") + @Schema(description = "所属模块ID,为空时归入全部需求模块", example = "1024") private Long moduleId; - @Schema(description = "是否需要评审(0不需要;1需要)", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @Schema(description = "是否需要评审,0不需要,1需要", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @NotNull(message = "是否需要评审不能为空") private Integer reviewRequired; @Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理") @NotBlank(message = "需求标题不能为空") - @Size(max = 200, message = "需求标题长度不能超过200个字符") + @Size(max = 200, message = "需求标题长度不能超过 200 个字符") private String title; - @Schema(description = "需求描述(富文本)", example = "详细描述需求内容
") + @Schema(description = "需求描述,支持富文本", example = "详细描述需求内容
") private String description; @Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function") @NotBlank(message = "需求分类不能为空") - @Size(max = 64, message = "需求分类长度不能超过64个字符") + @Size(max = 64, message = "需求分类长度不能超过 64 个字符") private String category; - @Schema(description = "优先级(0低 1中 2高 3紧急)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "优先级,0低、1中、2高、3紧急", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "优先级不能为空") private Integer priority; - @Schema(description = "提出人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "提出人不能为空") private Long proposerId; - @Schema(description = "当前处理人用户编号", example = "1024") + @Schema(description = "提出人姓名", example = "张三") + private String proposerNickname; + + @Schema(description = "所需工时", example = "8") + @NotNull(message = "所需工时不能为空") + private Double workHours; + + @Schema(description = "当前处理人用户ID", example = "1024") private Long currentHandlerUserId; + @Schema(description = "当前处理人姓名", example = "李四") + private String currentHandlerUserNickname; + @Schema(description = "默认实现项目编号", example = "1024") private Long implementProjectId; - @Schema(description = "预期完成时间", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "预期完成时间不能为空") - private LocalDateTime completionDate; - - @Schema(description = "排序值(越小越靠前)", example = "0") + @Schema(description = "排序值,越小越靠前", example = "0") private Integer sort; } diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/dataobject/product/ProductRequirementDO.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/dataobject/product/ProductRequirementDO.java index e81795c..05bf62f 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/dataobject/product/ProductRequirementDO.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/dataobject/product/ProductRequirementDO.java @@ -6,8 +6,6 @@ import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO; import lombok.Data; import lombok.EqualsAndHashCode; -import java.time.LocalDateTime; - /** * 产品需求主表 */ @@ -22,11 +20,11 @@ public class ProductRequirementDO extends BaseDO { @TableId private Long id; /** - * 父需求ID(0表示顶级需求) + * 父需求ID,0 表示顶级需求 */ private Long parentId; /** - * 所属模块ID(0表示全部需求) + * 所属模块ID,空表示全部需求 */ private Long moduleId; /** @@ -34,7 +32,7 @@ public class ProductRequirementDO extends BaseDO { */ private Long productId; /** - * 是否需要评审(0不需要;1需要) + * 是否需要评审,0不需要,1需要 */ private Integer reviewRequired; /** @@ -42,7 +40,7 @@ public class ProductRequirementDO extends BaseDO { */ private String title; /** - * 需求描述(富文本) + * 需求描述,支持富文本 */ private String description; /** @@ -50,7 +48,7 @@ public class ProductRequirementDO extends BaseDO { */ private String category; /** - * 来源类型(manual:手工新增, work_order:工单流转) + * 来源类型,manual 表示手工新增,work_order 表示工单流转 */ private String sourceType; /** @@ -58,7 +56,7 @@ public class ProductRequirementDO extends BaseDO { */ private Long sourceBizId; /** - * 优先级(0低 1中 2高 3紧急) + * 优先级,0低、1中、2高、3紧急 */ private Integer priority; /** @@ -74,9 +72,13 @@ public class ProductRequirementDO extends BaseDO { */ private Long proposerId; /** - * 提出人用户姓名快照 + * 提出人姓名快照 */ private String proposerNickname; + /** + * 所需工时 + */ + private Double workHours; /** * 当前处理人用户ID */ @@ -86,15 +88,11 @@ public class ProductRequirementDO extends BaseDO { */ private String currentHandlerUserNickname; /** - * 默认实现项目ID(分流后填写) + * 默认实现项目ID,分流后可回填 */ private Long implementProjectId; /** - * 预期完成时间 - */ - private LocalDateTime completionDate; - /** - * 排序值(越小越靠前) + * 排序值,越小越靠前 */ private Integer sort; diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java index dc4d105..0659e42 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java @@ -2,6 +2,7 @@ package com.njcn.rdms.module.project.service.product; import com.google.common.annotations.VisibleForTesting; import com.njcn.rdms.framework.common.pojo.PageResult; +import com.njcn.rdms.framework.common.util.json.JsonUtils; import com.njcn.rdms.framework.common.util.object.BeanUtils; import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils; import com.njcn.rdms.module.project.controller.admin.product.vo.requirement.*; @@ -25,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -56,6 +58,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService private static final List
* 构建逻辑:
* 1. 从目标用户向上追溯到根节点,记录上级链
* 2. 从根节点开始,只沿着包含目标用户的分支向下构建
- * 3. 构建目标用户的所有下级
+ * 3. 目标用户节点不构建下级
*
* @param targetUserId 目标用户ID
* @param context 树形结构上下文
* @return 目标用户相关的分支树形结构列表
*/
private List