feat(项目需求): 开发项目需求的富文本和附件功能。
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -37,13 +38,13 @@ public class ProductRequirementRespVO {
|
|||||||
@Schema(description = "需求分类名称", example = "功能需求")
|
@Schema(description = "需求分类名称", example = "功能需求")
|
||||||
private String categoryName;
|
private String categoryName;
|
||||||
|
|
||||||
@Schema(description = "需求来源类型,manual 表示手工新增,work_order 表示工单流转", requiredMode = Schema.RequiredMode.REQUIRED, example = "manual")
|
@Schema(description = "需求来源类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "manual")
|
||||||
private String sourceType;
|
private String sourceType;
|
||||||
|
|
||||||
@Schema(description = "来源业务ID", example = "1024")
|
@Schema(description = "来源业务ID", example = "1024")
|
||||||
private Long sourceBizId;
|
private Long sourceBizId;
|
||||||
|
|
||||||
@Schema(description = "优先级,0低、1中、2高、3紧急", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "优先级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
private Integer priority;
|
private Integer priority;
|
||||||
|
|
||||||
@Schema(description = "优先级名称", example = "中")
|
@Schema(description = "优先级名称", example = "中")
|
||||||
@@ -88,10 +89,13 @@ public class ProductRequirementRespVO {
|
|||||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
@Schema(description = "子需求列表,树形结构")
|
@Schema(description = "子需求列表,树形结构")
|
||||||
private List<ProductRequirementRespVO> children;
|
private List<ProductRequirementRespVO> children;
|
||||||
|
|
||||||
@Schema(description = "是否为终态,已拒绝、已取消、已关闭都算终态", example = "false")
|
@Schema(description = "是否为终态", example = "false")
|
||||||
private Boolean terminal;
|
private Boolean terminal;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 产品需求保存 Request VO
|
* 管理后台 - 产品需求保存 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -29,7 +33,7 @@ public class ProductRequirementSaveReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -37,7 +41,7 @@ public class ProductRequirementSaveReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
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")
|
||||||
@@ -67,4 +71,8 @@ public class ProductRequirementSaveReqVO {
|
|||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 产品需求拆分 Request VO
|
* 管理后台 - 产品需求拆分 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -30,7 +34,7 @@ public class ProductRequirementSplitReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -38,7 +42,7 @@ public class ProductRequirementSplitReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
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")
|
||||||
@@ -68,4 +72,8 @@ public class ProductRequirementSplitReqVO {
|
|||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.product.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 产品需求编辑 Request VO
|
* 管理后台 - 产品需求编辑 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -30,7 +34,7 @@ public class ProductRequirementUpdateReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -38,7 +42,7 @@ public class ProductRequirementUpdateReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
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")
|
||||||
@@ -68,4 +72,8 @@ public class ProductRequirementUpdateReqVO {
|
|||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -13,19 +14,19 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
public class ProjectRequirementRespVO {
|
public class ProjectRequirementRespVO {
|
||||||
|
|
||||||
@Schema(description = "需求 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "需求ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "父需求 ID,0 表示顶级需求", example = "0")
|
@Schema(description = "父需求ID,0 表示顶级需求", example = "0")
|
||||||
private Long parentId;
|
private Long parentId;
|
||||||
|
|
||||||
@Schema(description = "所属项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "所属项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
@Schema(description = "所属模块 ID", example = "1024")
|
@Schema(description = "所属模块ID", example = "1024")
|
||||||
private Long moduleId;
|
private Long moduleId;
|
||||||
|
|
||||||
@Schema(description = "是否需要评审,0 不需要,1 需要", example = "0")
|
@Schema(description = "是否需要评审,0不需要,1需要", example = "0")
|
||||||
private Integer reviewRequired;
|
private Integer reviewRequired;
|
||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@@ -43,7 +44,7 @@ public class ProjectRequirementRespVO {
|
|||||||
@Schema(description = "需求来源类型", example = "manual")
|
@Schema(description = "需求来源类型", example = "manual")
|
||||||
private String sourceType;
|
private String sourceType;
|
||||||
|
|
||||||
@Schema(description = "来源业务 ID", example = "1024")
|
@Schema(description = "来源业务ID", example = "1024")
|
||||||
private Long sourceBizId;
|
private Long sourceBizId;
|
||||||
|
|
||||||
@Schema(description = "优先级", example = "1")
|
@Schema(description = "优先级", example = "1")
|
||||||
@@ -61,19 +62,19 @@ public class ProjectRequirementRespVO {
|
|||||||
@Schema(description = "最近一次状态动作原因", example = "评审通过")
|
@Schema(description = "最近一次状态动作原因", example = "评审通过")
|
||||||
private String lastStatusReason;
|
private String lastStatusReason;
|
||||||
|
|
||||||
@Schema(description = "提出人用户 ID", example = "1024")
|
@Schema(description = "提出人用户ID", example = "1024")
|
||||||
private Long proposerId;
|
private Long proposerId;
|
||||||
|
|
||||||
@Schema(description = "提出人昵称", example = "张三")
|
@Schema(description = "提出人姓名", example = "张三")
|
||||||
private String proposerNickname;
|
private String proposerNickname;
|
||||||
|
|
||||||
@Schema(description = "所需工时", example = "8")
|
@Schema(description = "所需工时", example = "8")
|
||||||
private Double workHours;
|
private Double workHours;
|
||||||
|
|
||||||
@Schema(description = "当前处理人用户 ID", example = "1024")
|
@Schema(description = "当前处理人用户ID", example = "1024")
|
||||||
private Long currentHandlerUserId;
|
private Long currentHandlerUserId;
|
||||||
|
|
||||||
@Schema(description = "当前处理人昵称", example = "李四")
|
@Schema(description = "当前处理人姓名", example = "李四")
|
||||||
private String currentHandlerUserNickname;
|
private String currentHandlerUserNickname;
|
||||||
|
|
||||||
@Schema(description = "排序值", example = "0")
|
@Schema(description = "排序值", example = "0")
|
||||||
@@ -85,6 +86,9 @@ public class ProjectRequirementRespVO {
|
|||||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
@Schema(description = "子需求列表,树形结构")
|
@Schema(description = "子需求列表,树形结构")
|
||||||
private List<ProjectRequirementRespVO> children;
|
private List<ProjectRequirementRespVO> children;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 项目需求保存 Request VO
|
* 管理后台 - 项目需求保存 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -13,23 +17,23 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class ProjectRequirementSaveReqVO {
|
public class ProjectRequirementSaveReqVO {
|
||||||
|
|
||||||
@Schema(description = "需求 ID", example = "1024")
|
@Schema(description = "需求ID", example = "1024")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "所属项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "所属项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "项目 ID 不能为空")
|
@NotNull(message = "项目ID不能为空")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
@Schema(description = "所属模块 ID,为空时归入全部需求模块", example = "1024")
|
@Schema(description = "所属模块ID,为空时归入全部需求模块", example = "1024")
|
||||||
private Long moduleId;
|
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 = "是否需要评审不能为空")
|
@NotNull(message = "是否需要评审不能为空")
|
||||||
private Integer reviewRequired;
|
private Integer reviewRequired;
|
||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -37,31 +41,35 @@ public class ProjectRequirementSaveReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
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 = "优先级不能为空")
|
@NotNull(message = "优先级不能为空")
|
||||||
private Integer priority;
|
private Integer priority;
|
||||||
|
|
||||||
@Schema(description = "提出人用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "提出人不能为空")
|
@NotNull(message = "提出人不能为空")
|
||||||
private Long proposerId;
|
private Long proposerId;
|
||||||
|
|
||||||
@Schema(description = "提出人昵称", example = "张三")
|
@Schema(description = "提出人姓名", example = "张三")
|
||||||
private String proposerNickname;
|
private String proposerNickname;
|
||||||
|
|
||||||
@Schema(description = "所需工时", example = "8")
|
@Schema(description = "所需工时", example = "8")
|
||||||
@NotNull(message = "所需工时不能为空")
|
@NotNull(message = "所需工时不能为空")
|
||||||
private Double workHours;
|
private Double workHours;
|
||||||
|
|
||||||
@Schema(description = "当前处理人用户 ID", example = "1024")
|
@Schema(description = "当前处理人用户ID", example = "1024")
|
||||||
private Long currentHandlerUserId;
|
private Long currentHandlerUserId;
|
||||||
|
|
||||||
@Schema(description = "当前处理人昵称", example = "李四")
|
@Schema(description = "当前处理人姓名", example = "李四")
|
||||||
private String currentHandlerUserNickname;
|
private String currentHandlerUserNickname;
|
||||||
|
|
||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 项目需求拆分 Request VO
|
* 管理后台 - 项目需求拆分 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -13,24 +17,24 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class ProjectRequirementSplitReqVO {
|
public class ProjectRequirementSplitReqVO {
|
||||||
|
|
||||||
@Schema(description = "父需求 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "父需求ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "父需求 ID 不能为空")
|
@NotNull(message = "父需求ID不能为空")
|
||||||
private Long parentId;
|
private Long parentId;
|
||||||
|
|
||||||
@Schema(description = "所属项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "所属项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "项目 ID 不能为空")
|
@NotNull(message = "项目ID不能为空")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
@Schema(description = "所属模块 ID,为空时继承父需求模块", example = "1024")
|
@Schema(description = "所属模块ID,为空时继承父需求模块", example = "1024")
|
||||||
private Long moduleId;
|
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 = "是否需要评审不能为空")
|
@NotNull(message = "是否需要评审不能为空")
|
||||||
private Integer reviewRequired;
|
private Integer reviewRequired;
|
||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -38,31 +42,35 @@ public class ProjectRequirementSplitReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
@Schema(description = "优先级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "优先级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@NotNull(message = "优先级不能为空")
|
@NotNull(message = "优先级不能为空")
|
||||||
private Integer priority;
|
private Integer priority;
|
||||||
|
|
||||||
@Schema(description = "提出人用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "提出人不能为空")
|
@NotNull(message = "提出人不能为空")
|
||||||
private Long proposerId;
|
private Long proposerId;
|
||||||
|
|
||||||
@Schema(description = "提出人昵称", example = "张三")
|
@Schema(description = "提出人姓名", example = "张三")
|
||||||
private String proposerNickname;
|
private String proposerNickname;
|
||||||
|
|
||||||
@Schema(description = "所需工时", example = "8")
|
@Schema(description = "所需工时", example = "8")
|
||||||
@NotNull(message = "所需工时不能为空")
|
@NotNull(message = "所需工时不能为空")
|
||||||
private Double workHours;
|
private Double workHours;
|
||||||
|
|
||||||
@Schema(description = "当前处理人用户 ID", example = "1024")
|
@Schema(description = "当前处理人用户ID", example = "1024")
|
||||||
private Long currentHandlerUserId;
|
private Long currentHandlerUserId;
|
||||||
|
|
||||||
@Schema(description = "当前处理人昵称", example = "李四")
|
@Schema(description = "当前处理人姓名", example = "李四")
|
||||||
private String currentHandlerUserNickname;
|
private String currentHandlerUserNickname;
|
||||||
|
|
||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
package com.njcn.rdms.module.project.controller.admin.project.vo.requirement;
|
||||||
|
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理后台 - 项目需求编辑 Request VO
|
* 管理后台 - 项目需求编辑 Request VO
|
||||||
*/
|
*/
|
||||||
@@ -13,24 +17,24 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class ProjectRequirementUpdateReqVO {
|
public class ProjectRequirementUpdateReqVO {
|
||||||
|
|
||||||
@Schema(description = "需求 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "需求ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "需求 ID 不能为空")
|
@NotNull(message = "需求ID不能为空")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "所属项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "所属项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "项目 ID 不能为空")
|
@NotNull(message = "项目ID不能为空")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
@Schema(description = "所属模块 ID,为空时归入全部需求模块", example = "1024")
|
@Schema(description = "所属模块ID,为空时归入全部需求模块", example = "1024")
|
||||||
private Long moduleId;
|
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 = "是否需要评审不能为空")
|
@NotNull(message = "是否需要评审不能为空")
|
||||||
private Integer reviewRequired;
|
private Integer reviewRequired;
|
||||||
|
|
||||||
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
@Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "支持需求模块化管理")
|
||||||
@NotBlank(message = "需求标题不能为空")
|
@NotBlank(message = "需求标题不能为空")
|
||||||
@Size(max = 200, message = "需求标题长度不能超过 200 个字符")
|
@Size(max = 200, message = "需求标题长度不能超过200个字符")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
@Schema(description = "需求描述,支持富文本", example = "<p>详细描述需求内容</p>")
|
||||||
@@ -38,31 +42,35 @@ public class ProjectRequirementUpdateReqVO {
|
|||||||
|
|
||||||
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
@Schema(description = "需求分类字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "function")
|
||||||
@NotBlank(message = "需求分类不能为空")
|
@NotBlank(message = "需求分类不能为空")
|
||||||
@Size(max = 64, message = "需求分类长度不能超过 64 个字符")
|
@Size(max = 64, message = "需求分类长度不能超过64个字符")
|
||||||
private String category;
|
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 = "优先级不能为空")
|
@NotNull(message = "优先级不能为空")
|
||||||
private Integer priority;
|
private Integer priority;
|
||||||
|
|
||||||
@Schema(description = "提出人用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "提出人用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "提出人不能为空")
|
@NotNull(message = "提出人不能为空")
|
||||||
private Long proposerId;
|
private Long proposerId;
|
||||||
|
|
||||||
@Schema(description = "提出人昵称", example = "张三")
|
@Schema(description = "提出人姓名", example = "张三")
|
||||||
private String proposerNickname;
|
private String proposerNickname;
|
||||||
|
|
||||||
@Schema(description = "所需工时", example = "8")
|
@Schema(description = "所需工时", example = "8")
|
||||||
@NotNull(message = "所需工时不能为空")
|
@NotNull(message = "所需工时不能为空")
|
||||||
private Double workHours;
|
private Double workHours;
|
||||||
|
|
||||||
@Schema(description = "当前处理人用户 ID", example = "1024")
|
@Schema(description = "当前处理人用户ID", example = "1024")
|
||||||
private Long currentHandlerUserId;
|
private Long currentHandlerUserId;
|
||||||
|
|
||||||
@Schema(description = "当前处理人昵称", example = "李四")
|
@Schema(description = "当前处理人姓名", example = "李四")
|
||||||
private String currentHandlerUserNickname;
|
private String currentHandlerUserNickname;
|
||||||
|
|
||||||
@Schema(description = "排序值,越小越靠前", example = "0")
|
@Schema(description = "排序值,越小越靠前", example = "0")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "附件列表")
|
||||||
|
@Valid
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package com.njcn.rdms.module.project.dal.dataobject.product;
|
package com.njcn.rdms.module.project.dal.dataobject.product;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 产品需求主表
|
* 产品需求主表
|
||||||
*/
|
*/
|
||||||
@TableName("rdms_product_requirement")
|
@TableName(value = "rdms_product_requirement", autoResultMap = true)
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class ProductRequirementDO extends BaseDO {
|
public class ProductRequirementDO extends BaseDO {
|
||||||
@@ -95,5 +100,10 @@ public class ProductRequirementDO extends BaseDO {
|
|||||||
* 排序值,越小越靠前
|
* 排序值,越小越靠前
|
||||||
*/
|
*/
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
/**
|
||||||
|
* 闄勪欢鍒楄〃锛圝SON锛夈€傚厓绱?{@link AttachmentItem}锛歩d / url / name / size / contentType銆?
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package com.njcn.rdms.module.project.dal.dataobject.project;
|
package com.njcn.rdms.module.project.dal.dataobject.project;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.njcn.rdms.module.project.dal.dataobject.attachment.AttachmentItem;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目需求主表
|
* 项目需求主表
|
||||||
*/
|
*/
|
||||||
@TableName("rdms_project_requirement")
|
@TableName(value = "rdms_project_requirement", autoResultMap = true)
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class ProjectRequirementDO extends BaseDO {
|
public class ProjectRequirementDO extends BaseDO {
|
||||||
@@ -95,5 +100,10 @@ public class ProjectRequirementDO extends BaseDO {
|
|||||||
* 排序值
|
* 排序值
|
||||||
*/
|
*/
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
/**
|
||||||
|
* 闄勪欢鍒楄〃锛圝SON锛夈€傚厓绱?{@link AttachmentItem}锛歩d / url / name / size / contentType銆?
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import com.njcn.rdms.module.project.dal.mysql.project.ProjectRequirementModuleMa
|
|||||||
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
|
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
|
||||||
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
|
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
|
||||||
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
||||||
|
import com.njcn.rdms.module.project.framework.attachment.AttachmentFileIdResolver;
|
||||||
|
import com.njcn.rdms.module.project.framework.attachment.AttachmentValidator;
|
||||||
import com.njcn.rdms.module.project.framework.security.annotation.CheckObjectPermission;
|
import com.njcn.rdms.module.project.framework.security.annotation.CheckObjectPermission;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -108,6 +110,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
private ProjectRequirementModuleMapper projectRequirementModuleMapper;
|
private ProjectRequirementModuleMapper projectRequirementModuleMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private UserObjectRoleMapper userObjectRoleMapper;
|
private UserObjectRoleMapper userObjectRoleMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachmentFileIdResolver attachmentFileIdResolver;
|
||||||
|
|
||||||
// ========== 需求增删改查 ==========
|
// ========== 需求增删改查 ==========
|
||||||
|
|
||||||
@@ -120,6 +124,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
Long moduleId = resolveModuleId(createReqVO.getModuleId(), createReqVO.getProductId());
|
Long moduleId = resolveModuleId(createReqVO.getModuleId(), createReqVO.getProductId());
|
||||||
// 校验模块是否属于当前产品
|
// 校验模块是否属于当前产品
|
||||||
validateModuleBelongsToProduct(moduleId, createReqVO.getProductId());
|
validateModuleBelongsToProduct(moduleId, createReqVO.getProductId());
|
||||||
|
AttachmentValidator.validate(createReqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(createReqVO.getAttachments());
|
||||||
|
|
||||||
ProductRequirementDO requirement = new ProductRequirementDO();
|
ProductRequirementDO requirement = new ProductRequirementDO();
|
||||||
requirement.setProductId(createReqVO.getProductId());
|
requirement.setProductId(createReqVO.getProductId());
|
||||||
@@ -142,6 +148,7 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
requirement.setCurrentHandlerUserNickname(normalizeNullableText(createReqVO.getCurrentHandlerUserNickname()));
|
requirement.setCurrentHandlerUserNickname(normalizeNullableText(createReqVO.getCurrentHandlerUserNickname()));
|
||||||
requirement.setImplementProjectId(createReqVO.getImplementProjectId());
|
requirement.setImplementProjectId(createReqVO.getImplementProjectId());
|
||||||
requirement.setSort(createReqVO.getSort() != null ? createReqVO.getSort() : 0);
|
requirement.setSort(createReqVO.getSort() != null ? createReqVO.getSort() : 0);
|
||||||
|
requirement.setAttachments(createReqVO.getAttachments());
|
||||||
requirementMapper.insert(requirement);
|
requirementMapper.insert(requirement);
|
||||||
|
|
||||||
// 写入业务审计日志
|
// 写入业务审计日志
|
||||||
@@ -162,6 +169,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
Long moduleId = resolveModuleId(updateReqVO.getModuleId(), updateReqVO.getProductId());
|
Long moduleId = resolveModuleId(updateReqVO.getModuleId(), updateReqVO.getProductId());
|
||||||
// 校验模块是否属于当前产品
|
// 校验模块是否属于当前产品
|
||||||
validateModuleBelongsToProduct(moduleId, updateReqVO.getProductId());
|
validateModuleBelongsToProduct(moduleId, updateReqVO.getProductId());
|
||||||
|
AttachmentValidator.validate(updateReqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(updateReqVO.getAttachments());
|
||||||
|
|
||||||
ProductRequirementDO before = cloneRequirement(requirement);
|
ProductRequirementDO before = cloneRequirement(requirement);
|
||||||
String fromStatus = requirement.getStatusCode();
|
String fromStatus = requirement.getStatusCode();
|
||||||
@@ -178,6 +187,7 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
requirement.setCurrentHandlerUserNickname(normalizeNullableText(updateReqVO.getCurrentHandlerUserNickname()));
|
requirement.setCurrentHandlerUserNickname(normalizeNullableText(updateReqVO.getCurrentHandlerUserNickname()));
|
||||||
requirement.setImplementProjectId(updateReqVO.getImplementProjectId());
|
requirement.setImplementProjectId(updateReqVO.getImplementProjectId());
|
||||||
requirement.setSort(updateReqVO.getSort() != null ? updateReqVO.getSort() : 0);
|
requirement.setSort(updateReqVO.getSort() != null ? updateReqVO.getSort() : 0);
|
||||||
|
requirement.setAttachments(updateReqVO.getAttachments());
|
||||||
requirementMapper.updateById(requirement);
|
requirementMapper.updateById(requirement);
|
||||||
|
|
||||||
writeBizAuditLog(requirement, ACTION_UPDATE, fromStatus, requirement.getStatusCode(),
|
writeBizAuditLog(requirement, ACTION_UPDATE, fromStatus, requirement.getStatusCode(),
|
||||||
@@ -582,6 +592,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
validateRequirementNotDispatched(parentRequirement);
|
validateRequirementNotDispatched(parentRequirement);
|
||||||
// 校验父需求状态是否允许拆分(只能是待分流或实施中)
|
// 校验父需求状态是否允许拆分(只能是待分流或实施中)
|
||||||
validateParentAllowSplit(parentRequirement);
|
validateParentAllowSplit(parentRequirement);
|
||||||
|
AttachmentValidator.validate(reqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(reqVO.getAttachments());
|
||||||
|
|
||||||
// 创建子需求
|
// 创建子需求
|
||||||
ProductRequirementDO childRequirement = new ProductRequirementDO();
|
ProductRequirementDO childRequirement = new ProductRequirementDO();
|
||||||
@@ -606,6 +618,7 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
childRequirement.setCurrentHandlerUserNickname(normalizeNullableText(reqVO.getCurrentHandlerUserNickname()));
|
childRequirement.setCurrentHandlerUserNickname(normalizeNullableText(reqVO.getCurrentHandlerUserNickname()));
|
||||||
childRequirement.setImplementProjectId(reqVO.getImplementProjectId());
|
childRequirement.setImplementProjectId(reqVO.getImplementProjectId());
|
||||||
childRequirement.setSort(reqVO.getSort() != null ? reqVO.getSort() : 0);
|
childRequirement.setSort(reqVO.getSort() != null ? reqVO.getSort() : 0);
|
||||||
|
childRequirement.setAttachments(reqVO.getAttachments());
|
||||||
requirementMapper.insert(childRequirement);
|
requirementMapper.insert(childRequirement);
|
||||||
|
|
||||||
// 父需求状态从待分流变为实施中
|
// 父需求状态从待分流变为实施中
|
||||||
@@ -1257,6 +1270,7 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
||||||
target.setImplementProjectId(source.getImplementProjectId());
|
target.setImplementProjectId(source.getImplementProjectId());
|
||||||
target.setSort(source.getSort());
|
target.setSort(source.getSort());
|
||||||
|
target.setAttachments(source.getAttachments());
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1304,6 +1318,8 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
valueOf(after, ProductRequirementDO::getImplementProjectId));
|
valueOf(after, ProductRequirementDO::getImplementProjectId));
|
||||||
appendFieldChange(fieldChanges, "sort", valueOf(before, ProductRequirementDO::getSort),
|
appendFieldChange(fieldChanges, "sort", valueOf(before, ProductRequirementDO::getSort),
|
||||||
valueOf(after, ProductRequirementDO::getSort));
|
valueOf(after, ProductRequirementDO::getSort));
|
||||||
|
appendFieldChange(fieldChanges, "attachments", valueOf(before, ProductRequirementDO::getAttachments),
|
||||||
|
valueOf(after, ProductRequirementDO::getAttachments));
|
||||||
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1384,6 +1400,7 @@ public class ProductRequirementServiceImpl implements ProductRequirementService
|
|||||||
newRequirement.setCurrentHandlerUserId(productRequirement.getCurrentHandlerUserId());
|
newRequirement.setCurrentHandlerUserId(productRequirement.getCurrentHandlerUserId());
|
||||||
newRequirement.setCurrentHandlerUserNickname(productRequirement.getCurrentHandlerUserNickname());
|
newRequirement.setCurrentHandlerUserNickname(productRequirement.getCurrentHandlerUserNickname());
|
||||||
newRequirement.setWorkHours(productRequirement.getWorkHours());
|
newRequirement.setWorkHours(productRequirement.getWorkHours());
|
||||||
|
newRequirement.setAttachments(productRequirement.getAttachments());
|
||||||
newRequirement.setCreator(productRequirement.getCreator());
|
newRequirement.setCreator(productRequirement.getCreator());
|
||||||
newRequirement.setCreateTime(productRequirement.getCreateTime());
|
newRequirement.setCreateTime(productRequirement.getCreateTime());
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ import com.njcn.rdms.module.project.dal.mysql.project.ProjectRequirementStatusLo
|
|||||||
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
|
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
|
||||||
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
|
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
|
||||||
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
||||||
|
import com.njcn.rdms.module.project.framework.attachment.AttachmentFileIdResolver;
|
||||||
|
import com.njcn.rdms.module.project.framework.attachment.AttachmentValidator;
|
||||||
import com.njcn.rdms.module.project.framework.security.annotation.CheckObjectPermission;
|
import com.njcn.rdms.module.project.framework.security.annotation.CheckObjectPermission;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -122,6 +124,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
private ObjectStatusTransitionMapper statusTransitionMapper;
|
private ObjectStatusTransitionMapper statusTransitionMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ObjectStatusModelMapper statusModelMapper;
|
private ObjectStatusModelMapper statusModelMapper;
|
||||||
|
@Resource
|
||||||
|
private AttachmentFileIdResolver attachmentFileIdResolver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@@ -130,6 +134,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
public Long createRequirement(ProjectRequirementSaveReqVO createReqVO) {
|
public Long createRequirement(ProjectRequirementSaveReqVO createReqVO) {
|
||||||
Long moduleId = resolveModuleId(createReqVO.getModuleId(), createReqVO.getProjectId());
|
Long moduleId = resolveModuleId(createReqVO.getModuleId(), createReqVO.getProjectId());
|
||||||
validateModuleBelongsToProject(moduleId, createReqVO.getProjectId());
|
validateModuleBelongsToProject(moduleId, createReqVO.getProjectId());
|
||||||
|
AttachmentValidator.validate(createReqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(createReqVO.getAttachments());
|
||||||
|
|
||||||
ProjectRequirementDO requirement = new ProjectRequirementDO();
|
ProjectRequirementDO requirement = new ProjectRequirementDO();
|
||||||
requirement.setProjectId(createReqVO.getProjectId());
|
requirement.setProjectId(createReqVO.getProjectId());
|
||||||
@@ -150,6 +156,7 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
requirement.setCurrentHandlerUserId(createReqVO.getCurrentHandlerUserId());
|
requirement.setCurrentHandlerUserId(createReqVO.getCurrentHandlerUserId());
|
||||||
requirement.setCurrentHandlerUserNickname(normalizeNullableText(createReqVO.getCurrentHandlerUserNickname()));
|
requirement.setCurrentHandlerUserNickname(normalizeNullableText(createReqVO.getCurrentHandlerUserNickname()));
|
||||||
requirement.setSort(createReqVO.getSort() != null ? createReqVO.getSort() : 0);
|
requirement.setSort(createReqVO.getSort() != null ? createReqVO.getSort() : 0);
|
||||||
|
requirement.setAttachments(createReqVO.getAttachments());
|
||||||
requirementMapper.insert(requirement);
|
requirementMapper.insert(requirement);
|
||||||
|
|
||||||
writeBizAuditLog(requirement, ACTION_CREATE, null, initialStatus,
|
writeBizAuditLog(requirement, ACTION_CREATE, null, initialStatus,
|
||||||
@@ -168,6 +175,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
|
|
||||||
Long moduleId = resolveModuleId(updateReqVO.getModuleId(), updateReqVO.getProjectId());
|
Long moduleId = resolveModuleId(updateReqVO.getModuleId(), updateReqVO.getProjectId());
|
||||||
validateModuleBelongsToProject(moduleId, updateReqVO.getProjectId());
|
validateModuleBelongsToProject(moduleId, updateReqVO.getProjectId());
|
||||||
|
AttachmentValidator.validate(updateReqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(updateReqVO.getAttachments());
|
||||||
|
|
||||||
ProjectRequirementDO before = cloneRequirement(requirement);
|
ProjectRequirementDO before = cloneRequirement(requirement);
|
||||||
String fromStatus = requirement.getStatusCode();
|
String fromStatus = requirement.getStatusCode();
|
||||||
@@ -183,6 +192,7 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
requirement.setCurrentHandlerUserId(updateReqVO.getCurrentHandlerUserId());
|
requirement.setCurrentHandlerUserId(updateReqVO.getCurrentHandlerUserId());
|
||||||
requirement.setCurrentHandlerUserNickname(normalizeNullableText(updateReqVO.getCurrentHandlerUserNickname()));
|
requirement.setCurrentHandlerUserNickname(normalizeNullableText(updateReqVO.getCurrentHandlerUserNickname()));
|
||||||
requirement.setSort(updateReqVO.getSort() != null ? updateReqVO.getSort() : 0);
|
requirement.setSort(updateReqVO.getSort() != null ? updateReqVO.getSort() : 0);
|
||||||
|
requirement.setAttachments(updateReqVO.getAttachments());
|
||||||
requirementMapper.updateById(requirement);
|
requirementMapper.updateById(requirement);
|
||||||
|
|
||||||
writeBizAuditLog(requirement, ACTION_UPDATE, fromStatus, requirement.getStatusCode(),
|
writeBizAuditLog(requirement, ACTION_UPDATE, fromStatus, requirement.getStatusCode(),
|
||||||
@@ -346,6 +356,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
ProjectRequirementDO parentRequirement = validateRequirementExists(reqVO.getParentId());
|
ProjectRequirementDO parentRequirement = validateRequirementExists(reqVO.getParentId());
|
||||||
validateRequirementBelongsToProject(parentRequirement, reqVO.getProjectId());
|
validateRequirementBelongsToProject(parentRequirement, reqVO.getProjectId());
|
||||||
validateParentAllowSplit(parentRequirement);
|
validateParentAllowSplit(parentRequirement);
|
||||||
|
AttachmentValidator.validate(reqVO.getAttachments());
|
||||||
|
attachmentFileIdResolver.resolve(reqVO.getAttachments());
|
||||||
|
|
||||||
Long moduleId = reqVO.getModuleId() != null ? reqVO.getModuleId() : parentRequirement.getModuleId();
|
Long moduleId = reqVO.getModuleId() != null ? reqVO.getModuleId() : parentRequirement.getModuleId();
|
||||||
validateModuleBelongsToProject(moduleId, reqVO.getProjectId());
|
validateModuleBelongsToProject(moduleId, reqVO.getProjectId());
|
||||||
@@ -371,6 +383,7 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
childRequirement.setCurrentHandlerUserId(reqVO.getCurrentHandlerUserId());
|
childRequirement.setCurrentHandlerUserId(reqVO.getCurrentHandlerUserId());
|
||||||
childRequirement.setCurrentHandlerUserNickname(normalizeNullableText(reqVO.getCurrentHandlerUserNickname()));
|
childRequirement.setCurrentHandlerUserNickname(normalizeNullableText(reqVO.getCurrentHandlerUserNickname()));
|
||||||
childRequirement.setSort(reqVO.getSort() != null ? reqVO.getSort() : 0);
|
childRequirement.setSort(reqVO.getSort() != null ? reqVO.getSort() : 0);
|
||||||
|
childRequirement.setAttachments(reqVO.getAttachments());
|
||||||
requirementMapper.insert(childRequirement);
|
requirementMapper.insert(childRequirement);
|
||||||
|
|
||||||
writeBizAuditLog(childRequirement, ACTION_CREATE, null, initialStatus,
|
writeBizAuditLog(childRequirement, ACTION_CREATE, null, initialStatus,
|
||||||
@@ -1110,6 +1123,7 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
target.setCurrentHandlerUserId(source.getCurrentHandlerUserId());
|
target.setCurrentHandlerUserId(source.getCurrentHandlerUserId());
|
||||||
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
||||||
target.setSort(source.getSort());
|
target.setSort(source.getSort());
|
||||||
|
target.setAttachments(source.getAttachments());
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1158,6 +1172,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
valueOf(after, ProjectRequirementDO::getCurrentHandlerUserNickname));
|
valueOf(after, ProjectRequirementDO::getCurrentHandlerUserNickname));
|
||||||
appendFieldChange(fieldChanges, "sort", valueOf(before, ProjectRequirementDO::getSort),
|
appendFieldChange(fieldChanges, "sort", valueOf(before, ProjectRequirementDO::getSort),
|
||||||
valueOf(after, ProjectRequirementDO::getSort));
|
valueOf(after, ProjectRequirementDO::getSort));
|
||||||
|
appendFieldChange(fieldChanges, "attachments", valueOf(before, ProjectRequirementDO::getAttachments),
|
||||||
|
valueOf(after, ProjectRequirementDO::getAttachments));
|
||||||
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,6 +1234,7 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
target.setCurrentHandlerUserNickname(source.getCurrentHandlerUserNickname());
|
||||||
target.setImplementProjectId(source.getImplementProjectId());
|
target.setImplementProjectId(source.getImplementProjectId());
|
||||||
target.setSort(source.getSort());
|
target.setSort(source.getSort());
|
||||||
|
target.setAttachments(source.getAttachments());
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,6 +1279,8 @@ public class ProjectRequirementServiceImpl implements ProjectRequirementService
|
|||||||
valueOf(after, ProductRequirementDO::getImplementProjectId));
|
valueOf(after, ProductRequirementDO::getImplementProjectId));
|
||||||
appendFieldChange(fieldChanges, "sort", valueOf(before, ProductRequirementDO::getSort),
|
appendFieldChange(fieldChanges, "sort", valueOf(before, ProductRequirementDO::getSort),
|
||||||
valueOf(after, ProductRequirementDO::getSort));
|
valueOf(after, ProductRequirementDO::getSort));
|
||||||
|
appendFieldChange(fieldChanges, "attachments", valueOf(before, ProductRequirementDO::getAttachments),
|
||||||
|
valueOf(after, ProductRequirementDO::getAttachments));
|
||||||
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
return fieldChanges.isEmpty() ? null : JsonUtils.toJsonString(fieldChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user