feat: 缺陷列表添加缺陷缺陷来源

This commit is contained in:
chenjianxing 2021-05-24 11:00:50 +08:00 committed by jianxing
parent 856aff405e
commit 2b759037ae
17 changed files with 229 additions and 18 deletions

View File

@ -25,5 +25,9 @@ public class Issues implements Serializable {
private String creator; private String creator;
private Integer num;
private String resourceId;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -9,4 +9,5 @@ public class IssuesDao extends IssuesWithBLOBs {
private String model; private String model;
private String projectName; private String projectName;
private String creatorName; private String creatorName;
private String resourceName;
} }

View File

@ -783,6 +783,136 @@ public class IssuesExample {
addCriterion("creator not between", value1, value2, "creator"); addCriterion("creator not between", value1, value2, "creator");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andNumIsNull() {
addCriterion("num is null");
return (Criteria) this;
}
public Criteria andNumIsNotNull() {
addCriterion("num is not null");
return (Criteria) this;
}
public Criteria andNumEqualTo(Integer value) {
addCriterion("num =", value, "num");
return (Criteria) this;
}
public Criteria andNumNotEqualTo(Integer value) {
addCriterion("num <>", value, "num");
return (Criteria) this;
}
public Criteria andNumGreaterThan(Integer value) {
addCriterion("num >", value, "num");
return (Criteria) this;
}
public Criteria andNumGreaterThanOrEqualTo(Integer value) {
addCriterion("num >=", value, "num");
return (Criteria) this;
}
public Criteria andNumLessThan(Integer value) {
addCriterion("num <", value, "num");
return (Criteria) this;
}
public Criteria andNumLessThanOrEqualTo(Integer value) {
addCriterion("num <=", value, "num");
return (Criteria) this;
}
public Criteria andNumIn(List<Integer> values) {
addCriterion("num in", values, "num");
return (Criteria) this;
}
public Criteria andNumNotIn(List<Integer> values) {
addCriterion("num not in", values, "num");
return (Criteria) this;
}
public Criteria andNumBetween(Integer value1, Integer value2) {
addCriterion("num between", value1, value2, "num");
return (Criteria) this;
}
public Criteria andNumNotBetween(Integer value1, Integer value2) {
addCriterion("num not between", value1, value2, "num");
return (Criteria) this;
}
public Criteria andResourceIdIsNull() {
addCriterion("resource_id is null");
return (Criteria) this;
}
public Criteria andResourceIdIsNotNull() {
addCriterion("resource_id is not null");
return (Criteria) this;
}
public Criteria andResourceIdEqualTo(String value) {
addCriterion("resource_id =", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdNotEqualTo(String value) {
addCriterion("resource_id <>", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdGreaterThan(String value) {
addCriterion("resource_id >", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdGreaterThanOrEqualTo(String value) {
addCriterion("resource_id >=", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdLessThan(String value) {
addCriterion("resource_id <", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdLessThanOrEqualTo(String value) {
addCriterion("resource_id <=", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdLike(String value) {
addCriterion("resource_id like", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdNotLike(String value) {
addCriterion("resource_id not like", value, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdIn(List<String> values) {
addCriterion("resource_id in", values, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdNotIn(List<String> values) {
addCriterion("resource_id not in", values, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdBetween(String value1, String value2) {
addCriterion("resource_id between", value1, value2, "resourceId");
return (Criteria) this;
}
public Criteria andResourceIdNotBetween(String value1, String value2) {
addCriterion("resource_id not between", value1, value2, "resourceId");
return (Criteria) this;
}
} }
public static class Criteria extends GeneratedCriteria { public static class Criteria extends GeneratedCriteria {

View File

@ -12,6 +12,8 @@
<result column="platform" jdbcType="VARCHAR" property="platform" /> <result column="platform" jdbcType="VARCHAR" property="platform" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" /> <result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="creator" jdbcType="VARCHAR" property="creator" /> <result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="num" jdbcType="INTEGER" property="num" />
<result column="resource_id" jdbcType="VARCHAR" property="resourceId" />
</resultMap> </resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.IssuesWithBLOBs"> <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.IssuesWithBLOBs">
<result column="description" jdbcType="LONGVARCHAR" property="description" /> <result column="description" jdbcType="LONGVARCHAR" property="description" />
@ -77,7 +79,7 @@
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, title, `status`, create_time, update_time, reporter, lastmodify, platform, project_id, id, title, `status`, create_time, update_time, reporter, lastmodify, platform, project_id,
creator creator, num, resource_id
</sql> </sql>
<sql id="Blob_Column_List"> <sql id="Blob_Column_List">
description, custom_fields description, custom_fields
@ -134,13 +136,13 @@
insert into issues (id, title, `status`, insert into issues (id, title, `status`,
create_time, update_time, reporter, create_time, update_time, reporter,
lastmodify, platform, project_id, lastmodify, platform, project_id,
creator, description, custom_fields creator, num, resource_id,
) description, custom_fields)
values (#{id,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, values (#{id,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{reporter,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{reporter,jdbcType=VARCHAR},
#{lastmodify,jdbcType=VARCHAR}, #{platform,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{lastmodify,jdbcType=VARCHAR}, #{platform,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
#{creator,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR}, #{customFields,jdbcType=LONGVARCHAR} #{creator,jdbcType=VARCHAR}, #{num,jdbcType=INTEGER}, #{resourceId,jdbcType=VARCHAR},
) #{description,jdbcType=LONGVARCHAR}, #{customFields,jdbcType=LONGVARCHAR})
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.IssuesWithBLOBs"> <insert id="insertSelective" parameterType="io.metersphere.base.domain.IssuesWithBLOBs">
insert into issues insert into issues
@ -175,6 +177,12 @@
<if test="creator != null"> <if test="creator != null">
creator, creator,
</if> </if>
<if test="num != null">
num,
</if>
<if test="resourceId != null">
resource_id,
</if>
<if test="description != null"> <if test="description != null">
description, description,
</if> </if>
@ -213,6 +221,12 @@
<if test="creator != null"> <if test="creator != null">
#{creator,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR},
</if> </if>
<if test="num != null">
#{num,jdbcType=INTEGER},
</if>
<if test="resourceId != null">
#{resourceId,jdbcType=VARCHAR},
</if>
<if test="description != null"> <if test="description != null">
#{description,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR},
</if> </if>
@ -260,6 +274,12 @@
<if test="record.creator != null"> <if test="record.creator != null">
creator = #{record.creator,jdbcType=VARCHAR}, creator = #{record.creator,jdbcType=VARCHAR},
</if> </if>
<if test="record.num != null">
num = #{record.num,jdbcType=INTEGER},
</if>
<if test="record.resourceId != null">
resource_id = #{record.resourceId,jdbcType=VARCHAR},
</if>
<if test="record.description != null"> <if test="record.description != null">
description = #{record.description,jdbcType=LONGVARCHAR}, description = #{record.description,jdbcType=LONGVARCHAR},
</if> </if>
@ -283,6 +303,8 @@
platform = #{record.platform,jdbcType=VARCHAR}, platform = #{record.platform,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR}, project_id = #{record.projectId,jdbcType=VARCHAR},
creator = #{record.creator,jdbcType=VARCHAR}, creator = #{record.creator,jdbcType=VARCHAR},
num = #{record.num,jdbcType=INTEGER},
resource_id = #{record.resourceId,jdbcType=VARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR}, description = #{record.description,jdbcType=LONGVARCHAR},
custom_fields = #{record.customFields,jdbcType=LONGVARCHAR} custom_fields = #{record.customFields,jdbcType=LONGVARCHAR}
<if test="_parameter != null"> <if test="_parameter != null">
@ -300,7 +322,9 @@
lastmodify = #{record.lastmodify,jdbcType=VARCHAR}, lastmodify = #{record.lastmodify,jdbcType=VARCHAR},
platform = #{record.platform,jdbcType=VARCHAR}, platform = #{record.platform,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR}, project_id = #{record.projectId,jdbcType=VARCHAR},
creator = #{record.creator,jdbcType=VARCHAR} creator = #{record.creator,jdbcType=VARCHAR},
num = #{record.num,jdbcType=INTEGER},
resource_id = #{record.resourceId,jdbcType=VARCHAR}
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
</if> </if>
@ -335,6 +359,12 @@
<if test="creator != null"> <if test="creator != null">
creator = #{creator,jdbcType=VARCHAR}, creator = #{creator,jdbcType=VARCHAR},
</if> </if>
<if test="num != null">
num = #{num,jdbcType=INTEGER},
</if>
<if test="resourceId != null">
resource_id = #{resourceId,jdbcType=VARCHAR},
</if>
<if test="description != null"> <if test="description != null">
description = #{description,jdbcType=LONGVARCHAR}, description = #{description,jdbcType=LONGVARCHAR},
</if> </if>
@ -355,6 +385,8 @@
platform = #{platform,jdbcType=VARCHAR}, platform = #{platform,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR}, project_id = #{projectId,jdbcType=VARCHAR},
creator = #{creator,jdbcType=VARCHAR}, creator = #{creator,jdbcType=VARCHAR},
num = #{num,jdbcType=INTEGER},
resource_id = #{resourceId,jdbcType=VARCHAR},
description = #{description,jdbcType=LONGVARCHAR}, description = #{description,jdbcType=LONGVARCHAR},
custom_fields = #{customFields,jdbcType=LONGVARCHAR} custom_fields = #{customFields,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
@ -369,7 +401,9 @@
lastmodify = #{lastmodify,jdbcType=VARCHAR}, lastmodify = #{lastmodify,jdbcType=VARCHAR},
platform = #{platform,jdbcType=VARCHAR}, platform = #{platform,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR}, project_id = #{projectId,jdbcType=VARCHAR},
creator = #{creator,jdbcType=VARCHAR} creator = #{creator,jdbcType=VARCHAR},
num = #{num,jdbcType=INTEGER},
resource_id = #{resourceId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
</update> </update>
</mapper> </mapper>

View File

@ -14,7 +14,7 @@
<select id="getIssuesByProjectId" resultType="io.metersphere.base.domain.IssuesDao"> <select id="getIssuesByProjectId" resultType="io.metersphere.base.domain.IssuesDao">
select issues.id, ifnull(issues.title, '') as title, issues.project_id, issues.create_time, issues.update_time, select issues.id, ifnull(issues.title, '') as title, issues.project_id, issues.create_time, issues.update_time,
ifnull(issues.description, '') as description, issues.status, issues.platform, issues.custom_fields, issues.reporter, ifnull(issues.description, '') as description, issues.status, issues.platform, issues.custom_fields, issues.reporter,
issues.creator, issues.creator,issues.resource_id,
issues.lastmodify issues.lastmodify
from issues from issues
<include refid="queryWhereCondition"/> <include refid="queryWhereCondition"/>

View File

@ -52,6 +52,8 @@ public class IssuesService {
private IntegrationService integrationService; private IntegrationService integrationService;
@Resource @Resource
private ProjectService projectService; private ProjectService projectService;
@Resource
private TestPlanService testPlanService;
@Lazy @Lazy
@Resource @Resource
private TestCaseService testCaseService; private TestCaseService testCaseService;
@ -302,16 +304,29 @@ public class IssuesService {
// list.addAll(issue); // list.addAll(issue);
// }); // });
List<IssuesDao> issues = extIssuesMapper.getIssuesByProjectId(request); List<IssuesDao> issues = extIssuesMapper.getIssuesByProjectId(request);
List<String> ids = issues.stream() List<String> ids = issues.stream()
.map(IssuesDao::getCreator) .map(IssuesDao::getCreator)
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<String, User> userMap = ServiceUtils.getUserMap(ids); Map<String, User> userMap = ServiceUtils.getUserMap(ids);
List<String> resourceIds = issues.stream()
.map(IssuesDao::getResourceId)
.collect(Collectors.toList());
List<TestPlan> testPlans = testPlanService.getTestPlanByIds(resourceIds);
Map<String, String> planMap = testPlans.stream()
.collect(Collectors.toMap(TestPlan::getId, TestPlan::getName));
issues.forEach(item -> { issues.forEach(item -> {
User createUser = userMap.get(item.getCreator()); User createUser = userMap.get(item.getCreator());
if (createUser != null) { if (createUser != null) {
item.setCreatorName(createUser.getName()); item.setCreatorName(createUser.getName());
} }
if (planMap.get(item.getResourceId()) != null) {
item.setResourceName(planMap.get(item.getResourceId()));
}
}); });
// Map<String, List<IssuesDao>> issueMap = getIssueMap(issues); // Map<String, List<IssuesDao>> issueMap = getIssueMap(issues);
// Map<String, AbstractIssuePlatform> platformMap = getPlatformMap(request); // Map<String, AbstractIssuePlatform> platformMap = getPlatformMap(request);
// issueMap.forEach((platformName, data) -> { // issueMap.forEach((platformName, data) -> {

View File

@ -68,3 +68,8 @@ ALTER TABLE test_case_template ADD create_user VARCHAR(100) NULL;
ALTER TABLE issue_template ADD create_user VARCHAR(100) NULL; ALTER TABLE issue_template ADD create_user VARCHAR(100) NULL;
ALTER TABLE test_case_report_template ADD create_user VARCHAR(100) NULL; ALTER TABLE test_case_report_template ADD create_user VARCHAR(100) NULL;
ALTER TABLE api_test_environment ADD create_user VARCHAR(100) NULL; ALTER TABLE api_test_environment ADD create_user VARCHAR(100) NULL;
-- 缺陷来源
ALTER TABLE issues ADD resource_id varchar(50) DEFAULT NULL COMMENT 'Issue resource id';

View File

@ -1,14 +1,15 @@
<template> <template>
<ms-edit-dialog <ms-edit-dialog
:append-to-body="true"
:visible.sync="visible" :visible.sync="visible"
:title="'关联缺陷'" :title="$t('test_track.case.relate_issue')"
@confirm="save" @confirm="save"
ref="relevanceDialog"> ref="relevanceDialog">
<ms-table <ms-table
v-loading="page.result.loading" v-loading="page.result.loading"
:data="page.data" :data="page.data"
:condition="page.condition" :condition="page.condition"
:total="total" :total="page.total"
:page-size.sync="page.pageSize" :page-size.sync="page.pageSize"
:show-select-all="false" :show-select-all="false"
@handlePageChange="getIssues" @handlePageChange="getIssues"

View File

@ -49,6 +49,7 @@
<el-tab-pane :label="$t('test_track.case.relate_issue')" name="bug"> <el-tab-pane :label="$t('test_track.case.relate_issue')" name="bug">
<test-case-issue-relate <test-case-issue-relate
:plan-id="planId"
:read-only="readOnly && !(isTestPlan && isTesterPermission)" :read-only="readOnly && !(isTestPlan && isTesterPermission)"
:case-id="caseId" ref="issue"/> :case-id="caseId" ref="issue"/>
</el-tab-pane> </el-tab-pane>
@ -97,7 +98,7 @@ import FormRichTextItem from "@/business/components/track/case/components/FormRi
export default { export default {
name: "TestCaseEditOtherInfo", name: "TestCaseEditOtherInfo",
components: {FormRichTextItem, TestCaseIssueRelate, TestCaseAttachment, MsRichText, TestCaseRichText}, components: {FormRichTextItem, TestCaseIssueRelate, TestCaseAttachment, MsRichText, TestCaseRichText},
props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan'], props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId'],
data() { data() {
return { return {
result: {}, result: {},

View File

@ -61,7 +61,7 @@
</ms-table> </ms-table>
<test-plan-issue-edit :case-id="caseId" @refresh="getIssues" ref="issueEdit"/> <test-plan-issue-edit :plan-id="planId" :case-id="caseId" @refresh="getIssues" ref="issueEdit"/>
<IssueRelateList :case-id="caseId" @refresh="getIssues" ref="issueRelate"/> <IssueRelateList :case-id="caseId" @refresh="getIssues" ref="issueRelate"/>
</div> </div>
</template> </template>
@ -82,7 +82,7 @@ export default {
result: {}, result: {},
} }
}, },
props: ['caseId', 'readOnly'], props: ['caseId', 'readOnly','planId'],
computed: { computed: {
issueStatusMap() { issueStatusMap() {
return ISSUE_STATUS_MAP; return ISSUE_STATUS_MAP;

View File

@ -7,7 +7,7 @@
append-to-body append-to-body
ref="msEditDialog"> ref="msEditDialog">
<template v-slot:default="scope"> <template v-slot:default="scope">
<issue-edit-detail :case-id="caseId" :is-plan="true" @refresh="$emit('refresh')" @close="handleClose" ref="issueEditDetail"/> <issue-edit-detail :plan-id="planId" :case-id="caseId" :is-plan="true" @refresh="$emit('refresh')" @close="handleClose" ref="issueEditDetail"/>
</template> </template>
</ms-edit-dialog> </ms-edit-dialog>
</template> </template>
@ -30,7 +30,7 @@ export default {
return this.$store.state.projectId; return this.$store.state.projectId;
} }
}, },
props: ['caseId'], props: ['caseId', 'planId'],
methods: { methods: {
open(data) { open(data) {
this.visible = true; this.visible = true;

View File

@ -76,7 +76,7 @@ import {buildCustomFields, getTemplate, parseCustomField} from "@/common/js/cust
import CustomFiledComponent from "@/business/components/settings/workspace/template/CustomFiledComponent"; import CustomFiledComponent from "@/business/components/settings/workspace/template/CustomFiledComponent";
import TestCaseIssueList from "@/business/components/track/issue/TestCaseIssueList"; import TestCaseIssueList from "@/business/components/track/issue/TestCaseIssueList";
import IssueEditDetail from "@/business/components/track/issue/IssueEditDetail"; import IssueEditDetail from "@/business/components/track/issue/IssueEditDetail";
import {getCurrentUserId, getCurrentWorkspaceId} from "@/common/js/utils"; import {getCurrentUserId} from "@/common/js/utils";
export default { export default {
name: "IssueEditDetail", name: "IssueEditDetail",
@ -129,7 +129,8 @@ export default {
return false; return false;
} }
}, },
caseId: String caseId: String,
planId: String
}, },
computed: { computed: {
isSystem() { isSystem() {
@ -236,6 +237,9 @@ export default {
} else { } else {
param.testCaseIds = Array.from(this.testCaseContainIds); param.testCaseIds = Array.from(this.testCaseContainIds);
} }
if (this.planId) {
param.resourceId = this.planId;
}
return param; return param;
}, },
_save() { _save() {

View File

@ -46,6 +46,19 @@
prop="creatorName"> prop="creatorName">
</ms-table-column> </ms-table-column>
<ms-table-column
:label="$t('test_track.issue.issue_resource')"
prop="resourceName">
<template v-slot="scope">
<el-link v-if="scope.row.resourceName" @click="$router.push('/track/plan/view/' + scope.row.resourceId)">
{{scope.row.resourceName}}
</el-link>
<span v-else>
--
</span>
</template>
</ms-table-column>
<issue-description-table-item/> <issue-description-table-item/>
</ms-table> </ms-table>

View File

@ -81,7 +81,7 @@
<form-rich-text-item :label-width="formLabelWidth" v-if="testCase.stepModel === 'TEXT'" :disabled="true" :title="$t('test_track.case.expected_results')" :data="testCase" prop="expectedResult"/> <form-rich-text-item :label-width="formLabelWidth" v-if="testCase.stepModel === 'TEXT'" :disabled="true" :title="$t('test_track.case.expected_results')" :data="testCase" prop="expectedResult"/>
<form-rich-text-item :label-width="formLabelWidth" v-if="testCase.stepModel === 'TEXT'" :title="$t('test_track.plan_view.actual_result')" :data="testCase" prop="actualResult"/> <form-rich-text-item :label-width="formLabelWidth" v-if="testCase.stepModel === 'TEXT'" :title="$t('test_track.plan_view.actual_result')" :data="testCase" prop="actualResult"/>
<test-case-edit-other-info v-if="otherInfoActive" @openTest="openTest" :read-only="true" :is-test-plan="true" :project-id="projectId" :form="testCase" :case-id="testCase.caseId" ref="otherInfo"/> <test-case-edit-other-info :plan-id="testCase.planId" v-if="otherInfoActive" @openTest="openTest" :read-only="true" :is-test-plan="true" :project-id="projectId" :form="testCase" :case-id="testCase.caseId" ref="otherInfo"/>
</el-form> </el-form>
</div> </div>

View File

@ -1541,6 +1541,7 @@ export default {
}, },
issue: { issue: {
issue: "Issue", issue: "Issue",
issue_resource: "Issue source",
create_issue: "Create Issue", create_issue: "Create Issue",
add_issue: "Add Issue", add_issue: "Add Issue",
issue_list: "Issue List", issue_list: "Issue List",

View File

@ -1546,6 +1546,7 @@ export default {
}, },
issue: { issue: {
issue: "缺陷", issue: "缺陷",
issue_resource: "缺陷来源",
create_issue: "创建缺陷", create_issue: "创建缺陷",
add_issue: "添加缺陷", add_issue: "添加缺陷",
issue_list: "缺陷列表", issue_list: "缺陷列表",

View File

@ -1546,6 +1546,7 @@ export default {
}, },
issue: { issue: {
issue: "缺陷", issue: "缺陷",
issue_resource: "缺陷來源",
create_issue: "創建缺陷", create_issue: "創建缺陷",
add_issue: "添加缺陷", add_issue: "添加缺陷",
issue_list: "缺陷列表", issue_list: "缺陷列表",