diff --git a/xm-core/src/main/java/com/xm/core/ctrl/XmIterationController.java b/xm-core/src/main/java/com/xm/core/ctrl/XmIterationController.java index 26817d31..c0bb27c6 100644 --- a/xm-core/src/main/java/com/xm/core/ctrl/XmIterationController.java +++ b/xm-core/src/main/java/com/xm/core/ctrl/XmIterationController.java @@ -13,6 +13,7 @@ import com.mdp.safe.client.utils.LoginUtils; import com.mdp.sensitive.SensitiveWordService; import com.mdp.swagger.ApiEntityParams; import com.xm.core.entity.XmIteration; +import com.xm.core.entity.XmProduct; import com.xm.core.service.*; import com.xm.core.vo.XmIterationVo; import io.swagger.annotations.*; @@ -59,6 +60,10 @@ public class XmIterationController { @Autowired private XmRecordService xmRecordService; + + @Autowired + private XmGroupService groupService; + @Autowired XmIterationStateService xmIterationStateService; @@ -242,10 +247,14 @@ public class XmIterationController { return failed("data-0","迭代不存在"); } User user=LoginUtils.getCurrentUserInfo(); - boolean isPm= this.operQxService.checkIsProductAdmOrAss(xmProductService.getProductFromCache(iterationDb.getProductId()), user.getUserid()); - if( !isPm && !user.getUserid().equals(iterationDb.getAdminUserid()) && !user.getUserid().equals(iterationDb.getCuserid())){ + XmProduct xmProductDb=xmProductService.getProductFromCache(iterationDb.getProductId()); + boolean isPm=groupService.checkUserIsProductAdm(xmProductDb,user.getUserid()); + if( !isPm && !user.getUserid().equals(iterationDb.getAdminUserid()) && !user.getUserid().equals(iterationDb.getCuserid())){ return failed("no-qx","您无权删除,迭代创建人、负责人可以删除"); } + if(!isPm && !groupService.checkUserExistsProductGroup(xmProductDb.getId(),user.getUserid())){ + return failed("no-qx","您无权删除,您不是产品组成员。"); + } xmIterationService.deleteByPk(xmIteration); xmRecordService.addXmIterationRecord(xmIteration.getId(),"迭代-删除","删除迭代"+iterationDb.getIterationName(),"", JSON.toJSONString(iterationDb)); @@ -281,10 +290,13 @@ public class XmIterationController { return failed("data-0","迭代不存在"); } User user=LoginUtils.getCurrentUserInfo(); - boolean isPm= this.operQxService.checkIsProductAdmOrAss(xmProductService.getProductFromCache(iterationDb.getProductId()), user.getUserid()); - - if( !isPm && !user.getUserid().equals(iterationDb.getAdminUserid()) && user.getUserid().equals(iterationDb.getAdminUserid())){ - return failed("no-qx","您无权修改,迭代创建人、负责人可以修改"); + XmProduct xmProductDb=xmProductService.getProductFromCache(iterationDb.getProductId()); + boolean isPm=groupService.checkUserIsProductAdm(xmProductDb,user.getUserid()); + if( !isPm && !user.getUserid().equals(iterationDb.getAdminUserid()) && !user.getUserid().equals(iterationDb.getCuserid())){ + return failed("no-qx","您无权修改,产品经理、迭代创建人、负责人可以修改"); + } + if(!isPm && !groupService.checkUserExistsProductGroup(xmProductDb.getId(),user.getUserid())){ + return failed("no-qx","您无权修改,您不是产品组成员。"); } xmIterationService.updateByPk(xmIteration); if(!xmIteration.getAdminUserid().equals(iterationDb.getAdminUserid())){ @@ -339,12 +351,27 @@ public class XmIterationController { List can=new ArrayList<>(); List no=new ArrayList<>(); User user = LoginUtils.getCurrentUserInfo(); - for (XmIteration xmIterationDb : xmIterationsDb) { + XmIteration iterationDb=xmIterationsDb.get(0); + if(xmIterationsDb.stream().filter(k->!k.getProductId().equals(iterationDb.getProductId())).findAny().isPresent()){ + return failed("data-0","批量修改只能修改同一个产品下的迭代记录"); + } + XmProduct xmProductDb=xmProductService.getProductFromCache(iterationDb.getProductId()); + boolean isPm=groupService.checkUserIsProductAdm(xmProductDb,user.getUserid()); + if( !isPm && !user.getUserid().equals(iterationDb.getAdminUserid()) && !user.getUserid().equals(iterationDb.getCuserid())){ + return failed("no-qx","您无权修改,产品经理、迭代创建人、负责人可以修改"); + } + if(!isPm && !groupService.checkUserExistsProductGroup(xmProductDb.getId(),user.getUserid())){ + return failed("no-qx","您无权修改,您不是产品组成员。"); + } + for (XmIteration iterationDb2 : xmIterationsDb) { Tips tips2 = new Tips("检查通过"); + if( !isPm && !user.getUserid().equals(iterationDb2.getAdminUserid()) && !user.getUserid().equals(iterationDb2.getCuserid())){ + return failed("no-qx","您无权修改,产品经理、迭代创建人、负责人可以修改"); + } if(!tips2.isOk()){ - no.add(xmIterationDb); + no.add(iterationDb); }else{ - can.add(xmIterationDb); + can.add(iterationDb); } } if(can.size()>0){ diff --git a/xm-core/src/main/java/com/xm/core/entity/XmMenu.java b/xm-core/src/main/java/com/xm/core/entity/XmMenu.java index 0f7569a6..5004dd09 100644 --- a/xm-core/src/main/java/com/xm/core/entity/XmMenu.java +++ b/xm-core/src/main/java/com/xm/core/entity/XmMenu.java @@ -8,7 +8,7 @@ import java.util.Date; /** * 组织 com 顶级模块 xm 大模块 core 小模块
* 实体 XmMenu所有属性名:
- * "startTime","开始时间","menuId","功能编号","menuName","功能名称","pmenuId","上级功能","productId","归属产品编号","remark","备注","status","状态0初始1待评审2待设计3待开发4待sit测试5待uat测试6已测试待上线7已上线8已下线9已删除","online","是否已上线","demandUrl","需求链接","codeUrl","代码链接","designUrl","设计链接","docUrl","文档链接","helpUrl","帮助文档链接","operDocUrl","操作手册链接","seqNo","排序序号","mmUserid","故事管理员编号","mmUsername","故事管理员姓名","ctime","创建时间","ntype","节点类型0-叶子节点,1非叶子节点","sinceVersion","开始版本","childrenCnt","儿子节点个数","ltime","更新时间","tagIds","标签编号,逗号分割","tagNames","标签名称,逗号分割","pidPaths","父级id逗号分割,最后一个为本节点节点编号,以,号结尾","lvl","层级0-顶级,1-一级,2-二级,3-三级,4-四级。总共5级","isTpl","是否为模板","phaseId","计划编号","iterationId","迭代编号","source","需求来源","proposerId","提出人编号","proposerName","提出人姓名","dlvl","需求层次0-基础需求,1-增值需求,2-扩展需求","dtype","需求类型;0-新增功能;1-功能改进;2-bug修复;3-用户体验;4-UI优化;5-内部需求;6-删除需求;7-接口需求;","priority","优先级;0-紧急重要;1-紧急不重要;2-不紧急重要;3-不紧急不重要","dclass","需求分类1-史诗,2-特性,3-用户故事,4-任务,5-缺陷","iterationName","迭代名称","endTime","结束时间";
+ * "startTime","开始时间","menuId","功能编号","menuName","功能名称","pmenuId","上级功能","productId","归属产品编号","remark","备注","status","状态0初始1待评审2待设计3待开发4待sit测试5待uat测试6已测试待上线7已上线8已下线9已删除","online","是否已上线","demandUrl","需求链接","codeUrl","代码链接","designUrl","设计链接","docUrl","文档链接","helpUrl","帮助文档链接","operDocUrl","操作手册链接","seqNo","排序序号","mmUserid","故事管理员编号","mmUsername","故事管理员姓名","ctime","创建时间","ntype","节点类型0-叶子节点,1非叶子节点","sinceVersion","开始版本","childrenCnt","儿子节点个数","ltime","更新时间","tagIds","标签编号,逗号分割","tagNames","标签名称,逗号分割","pidPaths","父级id逗号分割,最后一个为本节点节点编号,以,号结尾","lvl","层级0-顶级,1-一级,2-二级,3-三级,4-四级。总共5级","isTpl","是否为模板","phaseId","计划编号","iterationId","迭代编号","source","需求来源","proposerId","提出人编号","proposerName","提出人姓名","dlvl","需求层次0-基础需求,1-增值需求,2-扩展需求","dtype","需求类型;0-新增功能;1-功能改进;2-bug修复;3-用户体验;4-UI优化;5-内部需求;6-删除需求;7-接口需求;","priority","优先级;0-紧急重要;1-紧急不重要;2-不紧急重要;3-不紧急不重要","dclass","需求分类1-史诗,2-特性,3-用户故事,4-任务,5-缺陷","iterationName","迭代名称","endTime","结束时间","funcId","功能菜单编号-故事才有","funcName","功能菜单名称-故事才有","comments","评论数","ups","点赞数","reads","阅读数";
* 当前主键(包括多主键):
* menu_id;
*/ @@ -132,6 +132,21 @@ public class XmMenu implements java.io.Serializable { @ApiModelProperty(notes="结束时间",allowEmptyValue=true,example="",allowableValues="") Date endTime; + + @ApiModelProperty(notes="功能菜单编号-故事才有",allowEmptyValue=true,example="",allowableValues="") + String funcId; + + @ApiModelProperty(notes="功能菜单名称-故事才有",allowEmptyValue=true,example="",allowableValues="") + String funcName; + + @ApiModelProperty(notes="评论数",allowEmptyValue=true,example="",allowableValues="") + Integer comments; + + @ApiModelProperty(notes="点赞数",allowEmptyValue=true,example="",allowableValues="") + Integer ups; + + @ApiModelProperty(notes="阅读数",allowEmptyValue=true,example="",allowableValues="") + Integer reads; /** *功能编号 diff --git a/xm-core/src/main/java/com/xm/core/entity/XmQuestion.java b/xm-core/src/main/java/com/xm/core/entity/XmQuestion.java index 7827ae00..59fc4c16 100644 --- a/xm-core/src/main/java/com/xm/core/entity/XmQuestion.java +++ b/xm-core/src/main/java/com/xm/core/entity/XmQuestion.java @@ -9,7 +9,7 @@ import java.math.BigDecimal; /** * 组织 com 顶级模块 xm 大模块 core 小模块
* 实体 XmQuestion所有属性名:
- * "id","问题编号","name","问题标题","projectId","项目编号","projectName","项目名称","caseId","测试案例编号","caseName","测试案例名称","endTime","到期时间","askUserid","提出人编号","askUsername","提出人","handlerUserid","处理人编号","handlerUsername","处理人","priority","优先级别1-非常紧急,2-紧急,3-一般紧急,4-低","solution","解决方案:","description","问题描述","createUserid","问题创建人编号","createUsername","问题创建人","createTime","创建时间","bugStatus","bug状态1|新提交2|处理中3|已修复4|重新打开5|已发布6|已拒绝7|挂起","bizProcInstId","当前流程实例编号","bizFlowState","当前流程状态0初始1审批中2审批通过3审批不通过4流程取消或者删除","menuId","故事编号","menuName","故事名称","budgetWorkload","预估工时单位人时","budgetAt","预估成本金额","actWorkload","实际工时(取报工实际工时汇总)","actAt","实际总金额","expectResult","期望结果","opStep","测试步骤","currResult","当前结果","refRequire","相关需求","bugSeverity","严重程度1、2、3、4,分别对应:致命缺陷、严重缺陷、普通缺陷、轻微缺陷","bugType","BUG类型1、2、3、4,分别对应:代码错误、低级缺陷、设计缺陷、配置相关、安全相关、性能问题、其他","tagIds","标签id列表逗号分隔","tagNames","标签名称列表逗号分隔","urls","链接地址列表逗号分隔","ltime","最后更新时间","qtype","问题类型2-风险、1-功能问题、3-普通咨询、(暂时不用这个字段了)","caseExecId","关联的案例执行编号","remarks","最后更新说明","productId","产品编号","repRate","复现频率1-必现,2-大概率复现,3-小概率复现,4-仅出现一次","verNum","版本号","vpath","访问路径/斜杠分割","pverNum","发布版本","bugReason","原因分析","rate","进度0-100","initWorkload","原始预估工作量,budget_workload发生变化后,进行备份","taskOut","是否众包0否1是","taskId","任务编号-可以在任务下直接创建bug","funcId","功能菜单编号","funcName","功能菜单名称","funcPnames","上级名称逗号分割","planId","测试计划编号","casedbId","测试库编号";
+ * "id","问题编号","name","问题标题","projectId","项目编号","projectName","项目名称","caseId","测试案例编号","caseName","测试案例名称","endTime","到期时间","askUserid","提出人编号","askUsername","提出人","handlerUserid","处理人编号","handlerUsername","处理人","priority","优先级别1-非常紧急,2-紧急,3-一般紧急,4-低","solution","解决方案:","description","问题描述","createUserid","问题创建人编号","createUsername","问题创建人","createTime","创建时间","bugStatus","bug状态1|新提交2|处理中3|已修复4|重新打开5|已发布6|已拒绝7|挂起","bizProcInstId","当前流程实例编号","bizFlowState","当前流程状态0初始1审批中2审批通过3审批不通过4流程取消或者删除","menuId","故事编号","menuName","故事名称","budgetWorkload","预估工时单位人时","budgetAt","预估成本金额","actWorkload","实际工时(取报工实际工时汇总)","actAt","实际总金额","expectResult","期望结果","opStep","测试步骤","currResult","当前结果","refRequire","相关需求","bugSeverity","严重程度1、2、3、4,分别对应:致命缺陷、严重缺陷、普通缺陷、轻微缺陷","bugType","BUG类型1、2、3、4,分别对应:代码错误、低级缺陷、设计缺陷、配置相关、安全相关、性能问题、其他","tagIds","标签id列表逗号分隔","tagNames","标签名称列表逗号分隔","urls","链接地址列表逗号分隔","ltime","最后更新时间","qtype","问题类型2-风险、1-功能问题、3-普通咨询、(暂时不用这个字段了)","caseExecId","关联的案例执行编号","remarks","最后更新说明","productId","产品编号","repRate","复现频率1-必现,2-大概率复现,3-小概率复现,4-仅出现一次","verNum","版本号","vpath","访问路径/斜杠分割","pverNum","发布版本","bugReason","原因分析","rate","进度0-100","initWorkload","原始预估工作量,budget_workload发生变化后,进行备份","taskOut","是否众包0否1是","taskId","任务编号-可以在任务下直接创建bug-废弃,不用了","funcId","功能菜单编号","funcName","功能菜单名称","funcPnames","上级名称逗号分割","planId","测试计划编号","casedbId","测试库编号";
* 当前主键(包括多主键):
* id;
*/ @@ -164,7 +164,7 @@ public class XmQuestion implements java.io.Serializable { @ApiModelProperty(notes="是否众包0否1是",allowEmptyValue=true,example="",allowableValues="") String taskOut; - @ApiModelProperty(notes="任务编号-可以在任务下直接创建bug",allowEmptyValue=true,example="",allowableValues="") + @ApiModelProperty(notes="任务编号-可以在任务下直接创建bug-废弃,不用了",allowEmptyValue=true,example="",allowableValues="") String taskId; @ApiModelProperty(notes="功能菜单编号",allowEmptyValue=true,example="",allowableValues="") diff --git a/xm-core/src/main/resources/mybatis/mapper/xm/core/dao/XmMenuMapper.xml b/xm-core/src/main/resources/mybatis/mapper/xm/core/dao/XmMenuMapper.xml index 5a48ddac..2fd9be12 100644 --- a/xm-core/src/main/resources/mybatis/mapper/xm/core/dao/XmMenuMapper.xml +++ b/xm-core/src/main/resources/mybatis/mapper/xm/core/dao/XmMenuMapper.xml @@ -328,7 +328,7 @@ insert into xm_menu( ) values ( - #{startTime},#{menuId},#{menuName},#{pmenuId},#{productId},#{remark},#{status},#{online},#{demandUrl},#{codeUrl},#{designUrl},#{docUrl},#{helpUrl},#{operDocUrl},#{seqNo},#{mmUserid},#{mmUsername},#{ctime},#{ntype},#{sinceVersion},#{childrenCnt},#{ltime},#{tagIds},#{tagNames},#{pidPaths},#{lvl},#{isTpl},#{phaseId},#{iterationId},#{source},#{proposerId},#{proposerName},#{dlvl},#{dtype},#{priority},#{dclass},#{iterationName},#{endTime} + #{startTime},#{menuId},#{menuName},#{pmenuId},#{productId},#{remark},#{status},#{online},#{demandUrl},#{codeUrl},#{designUrl},#{docUrl},#{helpUrl},#{operDocUrl},#{seqNo},#{mmUserid},#{mmUsername},#{ctime},#{ntype},#{sinceVersion},#{childrenCnt},#{ltime},#{tagIds},#{tagNames},#{pidPaths},#{lvl},#{isTpl},#{phaseId},#{iterationId},#{source},#{proposerId},#{proposerName},#{dlvl},#{dtype},#{priority},#{dclass},#{iterationName},#{endTime},#{funcId},#{funcName},#{comments},#{ups},#{reads} ) @@ -403,7 +403,7 @@ - start_time,menu_id,menu_name,pmenu_id,product_id,remark,status,online,demand_url,code_url,design_url,doc_url,help_url,oper_doc_url,seq_no,mm_userid,mm_username,ctime,ntype,since_version,children_cnt,ltime,tag_ids,tag_names,pid_paths,lvl,is_tpl,phase_id,iteration_id,source,proposer_id,proposer_name,dlvl,dtype,priority,dclass,iteration_name,end_time + start_time,menu_id,menu_name,pmenu_id,product_id,remark,status,online,demand_url,code_url,design_url,doc_url,help_url,oper_doc_url,seq_no,mm_userid,mm_username,ctime,ntype,since_version,children_cnt,ltime,tag_ids,tag_names,pid_paths,lvl,is_tpl,phase_id,iteration_id,source,proposer_id,proposer_name,dlvl,dtype,priority,dclass,iteration_name,end_time,func_id,func_name,comments,ups,reads @@ -446,6 +446,11 @@ and res.dclass = #{dclass} and res.iteration_name = #{iterationName} and date_format(res.end_time,'%Y-%m-%d') = date_format(#{endTime},'%Y-%m-%d') + and res.func_id = #{funcId} + and res.func_name = #{funcName} + and res.comments = #{comments} + and res.ups = #{ups} + and res.reads = #{reads} @@ -485,7 +490,12 @@ priority = #{priority}, dclass = #{dclass}, iteration_name = #{iterationName}, - end_time = #{endTime} + end_time = #{endTime}, + func_id = #{funcId}, + func_name = #{funcName}, + comments = #{comments}, + ups = #{ups}, + reads = #{reads} start_time = #{startTime}, @@ -525,6 +535,11 @@ dclass = #{dclass}, iteration_name = #{iterationName}, end_time = #{endTime}, + func_id = #{funcId}, + func_name = #{funcName}, + comments = #{comments}, + ups = #{ups}, + reads = #{reads}, @@ -564,6 +579,11 @@ priority = #{item.priority}, dclass = #{item.dclass}, iteration_name = #{item.iterationName}, - end_time = #{item.endTime} + end_time = #{item.endTime}, + func_id = #{item.funcId}, + func_name = #{item.funcName}, + comments = #{item.comments}, + ups = #{item.ups}, + reads = #{item.reads} \ No newline at end of file