This commit is contained in:
chenjianxing 2020-09-22 10:36:23 +08:00
commit c347c1d56d
16 changed files with 150 additions and 121 deletions

View File

@ -28,5 +28,7 @@ public class Issues implements Serializable {
private String projectName;
private String currentOwner;
private static final long serialVersionUID = 1L;
}
}

View File

@ -76,7 +76,7 @@ public class MailService {
"<body style=\"text-align: left\">\n" +
" <div>\n" +
" <h3>" + type + "定时任务结果通知</h3>\n" +
" <p> 尊敬的用户:您好,您所执行的" + testName + "运行失败,请点击报告链接查看</p>\n" +
" <p> 尊敬的用户:您好,您所执行的" + testName + "运行失败</p>\n" +
" </div>\n" +
"</body>\n" +
"</html>";
@ -89,7 +89,7 @@ public class MailService {
"<body style=\"text-align: left\">\n" +
" <div>\n" +
" <h3>" + type + "定时任务结果通知</h3>\n" +
" <p> 尊敬的用户:您好," + testName + "运行成功,请点击报告链接查看</p>\n" +
" <p> 尊敬的用户:您好," + testName + "运行成功</p>\n" +
" </div>\n" +
"</body>\n" +
"</html>";

View File

@ -238,8 +238,17 @@ public class PerformanceTestService {
startEngine(loadTest, engine, request.getTriggerMode());
if (request.getTriggerMode().equals("SCHEDULE")) {
List<Notice> notice = noticeService.queryNotice(request.getId());
mailService.sendHtml(engine.getReportId(), notice, "status", "performance");
List<Notice> notice = null;
try {
notice = noticeService.queryNotice(request.getId());
} catch (Exception e) {
e.printStackTrace();
}
try {
mailService.sendHtml(engine.getReportId(), notice, "status", "performance");
} catch (Exception e) {
e.printStackTrace();
}
}
return engine.getReportId();
}

View File

@ -67,7 +67,7 @@ public class TestCaseReviewController {
@PostMapping("/edit")
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public void editCaseReview(@RequestBody TestCaseReview testCaseReview) {
public void editCaseReview(@RequestBody SaveTestCaseReviewRequest testCaseReview) {
testCaseReviewService.editCaseReview(testCaseReview);
}

View File

@ -26,6 +26,8 @@ import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@ -54,6 +56,10 @@ public class TestCaseReviewService {
ExtProjectMapper extProjectMapper;
@Resource
UserService userService;
@Resource
TestCaseMapper testCaseMapper;
@Resource
TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper;
public void saveTestCaseReview(SaveTestCaseReviewRequest reviewRequest) {
checkCaseReviewExist(reviewRequest);
@ -119,20 +125,87 @@ public class TestCaseReviewService {
.collect(Collectors.toList());
UserExample userExample = new UserExample();
userExample.createCriteria().andIdIn(userIds);
return userMapper.selectByExample(userExample);
UserExample.Criteria criteria = userExample.createCriteria();
if (!CollectionUtils.isEmpty(userIds)) {
criteria.andIdIn(userIds);
return userMapper.selectByExample(userExample);
}
return new ArrayList<>();
}
public List<TestCaseReviewDTO> recent(String currentWorkspaceId) {
return extTestCaseReviewMapper.listByWorkspaceId(currentWorkspaceId);
}
public void editCaseReview(TestCaseReview testCaseReview) {
public void editCaseReview(SaveTestCaseReviewRequest testCaseReview) {
editCaseReviewer(testCaseReview);
editCaseReviewProject(testCaseReview);
testCaseReview.setUpdateTime(System.currentTimeMillis());
checkCaseReviewExist(testCaseReview);
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
}
private void editCaseReviewer(SaveTestCaseReviewRequest testCaseReview) {
// 要更新的reviewerIds
List<String> reviewerIds = testCaseReview.getUserIds();
String id = testCaseReview.getId();
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(id);
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
List<String> dbReviewIds = testCaseReviewUsers.stream().map(TestCaseReviewUsers::getUserId).collect(Collectors.toList());
reviewerIds.forEach(reviewerId -> {
if (!dbReviewIds.contains(reviewerId)) {
TestCaseReviewUsers caseReviewUser = new TestCaseReviewUsers();
caseReviewUser.setUserId(reviewerId);
caseReviewUser.setReviewId(id);
testCaseReviewUsersMapper.insertSelective(caseReviewUser);
}
});
TestCaseReviewUsersExample example = new TestCaseReviewUsersExample();
example.createCriteria().andReviewIdEqualTo(id).andUserIdNotIn(reviewerIds);
testCaseReviewUsersMapper.deleteByExample(example);
}
private void editCaseReviewProject(SaveTestCaseReviewRequest testCaseReview) {
List<String> projectIds = testCaseReview.getProjectIds();
String id = testCaseReview.getId();
if (!CollectionUtils.isEmpty(projectIds)) {
TestCaseReviewProjectExample testCaseReviewProjectExample = new TestCaseReviewProjectExample();
testCaseReviewProjectExample.createCriteria().andReviewIdEqualTo(id);
List<TestCaseReviewProject> testCaseReviewProjects = testCaseReviewProjectMapper.selectByExample(testCaseReviewProjectExample);
List<String> dbProjectIds = testCaseReviewProjects.stream().map(TestCaseReviewProject::getProjectId).collect(Collectors.toList());
projectIds.forEach(projectId -> {
if (!dbProjectIds.contains(projectId)) {
TestCaseReviewProject testCaseReviewProject = new TestCaseReviewProject();
testCaseReviewProject.setReviewId(id);
testCaseReviewProject.setProjectId(projectId);
testCaseReviewProjectMapper.insert(testCaseReviewProject);
}
});
TestCaseReviewProjectExample example = new TestCaseReviewProjectExample();
example.createCriteria().andReviewIdEqualTo(id).andProjectIdNotIn(projectIds);
testCaseReviewProjectMapper.deleteByExample(example);
// 关联的项目下的用例idList
TestCaseExample testCaseExample = new TestCaseExample();
testCaseExample.createCriteria().andProjectIdIn(projectIds);
List<TestCase> caseList = testCaseMapper.selectByExample(testCaseExample);
List<String> caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
TestCaseReviewTestCaseExample testCaseReviewTestCaseExample = new TestCaseReviewTestCaseExample();
TestCaseReviewTestCaseExample.Criteria criteria = testCaseReviewTestCaseExample.createCriteria().andReviewIdEqualTo(id);
if (!CollectionUtils.isEmpty(caseIds)) {
criteria.andCaseIdNotIn(caseIds);
}
testCaseReviewTestCaseMapper.deleteByExample(testCaseReviewTestCaseExample);
}
}
private void checkCaseReviewExist(TestCaseReview testCaseReview) {
if (testCaseReview.getName() != null) {
TestCaseReviewExample example = new TestCaseReviewExample();

View File

@ -187,6 +187,7 @@
this.form.cronValue = this.schedule.value;
listenGoBack(this.close);
this.handleClick()
this.activeName = 'first'
},
crontabFill(value, resultList) {
//

View File

@ -5,7 +5,7 @@
<ms-table-button :is-tester-permission="true" v-if="!showMyCreator" icon="el-icon-view"
content="我创建的评审" @click="searchMyCreator"/>
<ms-table-button :is-tester-permission="true" v-if="showMyCreator" icon="el-icon-view"
content="我待审核的评审" @click="searchMyCreator"/>
content="待我评审" @click="searchMyCreator"/>
</div>
</template>

View File

@ -154,6 +154,7 @@
},
methods: {
openTestCaseRelevanceDialog() {
this.getProject();
this.initData();
this.dialogFormVisible = true;
},
@ -219,7 +220,6 @@
initData() {
this.getCaseNames();
this.getAllNodeTreeByPlanId();
this.getProject();
},
refresh() {
this.close();

View File

@ -48,7 +48,7 @@
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="lastmodify"
prop="currentOwner"
:label="$t('test_track.module.current_owner')"
show-overflow-tooltip>
</el-table-column>

View File

@ -25,7 +25,6 @@
<el-col :span="11" :offset="2">
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
<el-select
:disabled="(form.status == null) ? false : true"
v-model="form.projectIds"
:placeholder="$t('test_track.plan.input_plan_project')"
multiple
@ -45,13 +44,12 @@
<el-row>
<el-col :span="10" :offset="1">
<el-form-item label="评审人" :label-width="formLabelWidth" prop="principal">
<el-form-item label="评审人" :label-width="formLabelWidth" prop="userIds">
<el-select
v-model="form.userIds"
placeholder="请选择评审人"
filterable multiple
collapse-tags
:disabled="(form.status == null) ? false : true"
>
<el-option
v-for="item in reviewerOptions"
@ -132,6 +130,7 @@ export default {
description: '',
endTime: ''
},
dbProjectIds: [],
rules: {
name: [
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
@ -161,6 +160,7 @@ export default {
let tmp = {};
Object.assign(tmp, caseReview);
Object.assign(this.form, tmp);
this.dbProjectIds = JSON.parse(JSON.stringify(this.form.projectIds));
}
listenGoBack(this.close);
this.dialogFormVisible = true;
@ -178,16 +178,44 @@ export default {
if (this.operationType === 'save') {
this.compareTime(new Date().getTime(), this.form.endTime);
}
this.$post('/test/case/review/' + this.operationType, param, () => {
this.$success(this.$t('commons.save_success'));
this.dialogFormVisible = false;
this.$emit("refresh");
});
if (this.operationType === 'edit') {
const nowIds = param.projectIds;
let sign = true;
this.dbProjectIds.forEach(dbId => {
if (nowIds.indexOf(dbId) === -1 && sign) {
sign = false;
this.$confirm('取消项目关联会同时取消该项目下已关联的测试用例', '提示', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.editTestReview(param);
}).catch(() => {
this.$info(this.$t('commons.cancel'))
});
}
});
if (sign) {
this.editTestReview(param);
}
} else {
this.editTestReview(param);
}
} else {
return false;
}
});
},
editTestReview(param) {
this.$post('/test/case/review/' + this.operationType, param, () => {
this.$success(this.$t('commons.save_success'));
this.dialogFormVisible = false;
this.$emit("refresh");
});
},
getProjects() {
this.result = this.$get("/project/listAll", (response) => {
if (response.success) {
@ -204,7 +232,8 @@ export default {
});
},
statusChange(status) {
this.form.status = status;
this.$forceUpdate();
},
close() {
removeGoBackListener(this.close);

View File

@ -37,42 +37,14 @@
<el-table-column
prop="status"
column-key="status"
:filters="statusFilters"
:label="$t('test_track.plan.plan_status')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span @click.stop="clickt = 'stop'">
<el-dropdown class="test-case-status" @command="statusChange">
<span class="el-dropdown-link">
<plan-status-table-item :value="scope.row.status"/>
</span>
<el-dropdown-menu slot="dropdown" chang>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Prepare'}">
{{ $t('test_track.plan.plan_status_prepare') }}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Underway'}">
{{ $t('test_track.plan.plan_status_running') }}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Completed'}">
{{ $t('test_track.plan.plan_status_completed') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span class="el-dropdown-link">
<plan-status-table-item :value="scope.row.status"/>
</span>
</template>
</el-table-column>
<!-- <el-table-column-->
<!-- prop="reviewerSize"-->
<!-- label="已评"-->
<!-- show-overflow-tooltip>-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- prop="resultMap"-->
<!-- label="结果分布"-->
<!-- show-overflow-tooltip>-->
<!-- </el-table-column>-->
<el-table-column
prop="createTime"
:label="$t('commons.create_time')"
@ -94,10 +66,10 @@
<template v-slot:default="scope">
<ms-table-operator :is-tester-permission="true" @editClick="handleEdit(scope.row)"
@deleteClick="handleDelete(scope.row)">
<template v-slot:middle>
<ms-table-operator-button :isTesterPermission="true" type="success" tip="重新发起" icon="el-icon-document"
@exec="reCreate(scope.row)"/>
</template>
<!-- <template v-slot:middle>-->
<!-- <ms-table-operator-button :isTesterPermission="true" type="success" tip="重新发起" icon="el-icon-document"-->
<!-- @exec="reCreate(scope.row)"/>-->
<!-- </template>-->
</ms-table-operator>
</template>
</el-table-column>
@ -105,7 +77,7 @@
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<ms-delete-confirm title="删除用例评审" @delete="_handleDelete" ref="deleteConfirm"/>
<ms-delete-confirm title="取消用例关联" @delete="_handleDelete" ref="deleteConfirm"/>
</el-card>
</template>
@ -217,9 +189,6 @@ export default {
_sort(column, this.condition);
this.initTableData();
},
reCreate() {
}
}
}
</script>

View File

@ -154,6 +154,7 @@ export default {
},
methods: {
openTestReviewRelevanceDialog() {
this.getProject();
this.initData();
this.dialogFormVisible = true;
},
@ -217,7 +218,6 @@ export default {
initData() {
this.getReviews();
this.getAllNodeTreeByPlanId();
this.getProject();
},
refresh() {
this.close();
@ -225,7 +225,7 @@ export default {
getAllNodeTreeByPlanId() {
if (this.reviewId) {
let param = {
testPlanId: this.reviewId,
reviewId: this.reviewId,
projectId: this.projectId
};
this.result = this.$post("/case/node/list/all/review", param , response => {

View File

@ -95,37 +95,6 @@
show-overflow-tooltip>
</el-table-column>
<el-table-column
:label="$t('test_track.issue.issue')"
show-overflow-tooltip>
<template v-slot:default="scope">
<el-popover
placement="right"
width="400"
trigger="hover">
<el-table border class="adjust-table" :data="scope.row.issuesContent" style="width: 100%">
<el-table-column prop="title" :label="$t('test_track.issue.title')" show-overflow-tooltip/>
<el-table-column prop="description" :label="$t('test_track.issue.description')">
<template v-slot:default="scope">
<el-popover
placement="left"
width="400"
trigger="hover"
>
<ckeditor :editor="editor" disabled :config="editorConfig"
v-model="scope.row.description"/>
<el-button slot="reference" type="text">{{$t('test_track.issue.preview')}}</el-button>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="platform" :label="$t('test_track.issue.platform')"/>
</el-table>
<el-button slot="reference" type="text">{{scope.row.issuesSize}}</el-button>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="reviewerName"
label="评审人"
@ -139,20 +108,8 @@
column-key="status"
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<span @click.stop="clickt = 'stop'">
<el-dropdown class="test-case-status" @command="statusChange">
<span class="el-dropdown-link">
<status-table-item :value="scope.row.status"/>
</span>
<el-dropdown-menu slot="dropdown" chang>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Pass'}">
{{$t('test_track.plan_view.pass')}}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'UnPass'}">
未通过
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span class="el-dropdown-link">
<status-table-item :value="scope.row.status"/>
</span>
</template>
</el-table-column>
@ -320,18 +277,6 @@ export default {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i]) {
this.$set(this.tableData[i], "issuesSize", 0);
this.$get("/issues/get/" + this.tableData[i].caseId, response => {
let issues = response.data;
if (this.tableData[i]) {
this.$set(this.tableData[i], "issuesSize", issues.length);
this.$set(this.tableData[i], "issuesContent", issues);
}
})
}
}
this.selectRows.clear();
});
}
@ -502,6 +447,7 @@ export default {
},
startReview() {
if (this.tableData.length !== 0) {
this.isReadOnly = false;
this.$refs.testReviewTestCaseEdit.openTestCaseEdit(this.tableData[0]);
} else {
this.$warning("没有关联的评审!");

View File

@ -936,7 +936,7 @@ export default {
performance: "Number of performance tests",
resource_pool: "Available test resource pool",
max_threads: "Maximum Concurrency",
duration: "Stress test duration",
duration: "Stress test duration(minutes)",
use_default: "Use default quota",
yes: "Yes",
no: "No",

View File

@ -938,7 +938,7 @@ export default {
performance: "性能测试数量",
resource_pool: "可用测试资源池",
max_threads: "最大并发数",
duration: "压测时长",
duration: "压测时长(分钟)",
use_default: "使用默认配额",
yes: "是",
no: "否",

View File

@ -938,7 +938,7 @@ export default {
performance: "性能測試數量",
resource_pool: "可用測試資源池",
max_threads: "最大並發數",
duration: "壓測時長",
duration: "壓測時長(分鐘)",
use_default: "使用默認配額",
yes: "是",
no: "否",