Merge branch 'v1.4' into master
This commit is contained in:
commit
32f130c05e
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.track.dto.TestCaseCommentDTO;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtTestCaseCommentMapper {
|
||||
|
||||
/**
|
||||
* 获取用例的评论
|
||||
* @param caseId
|
||||
* @return
|
||||
*/
|
||||
List<TestCaseCommentDTO> getCaseComments(@Param("caseId") String caseId);
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseCommentMapper">
|
||||
|
||||
<select id="getCaseComments" resultType="io.metersphere.track.dto.TestCaseCommentDTO"
|
||||
parameterType="java.lang.String">
|
||||
select *, user.name as authorName from test_case_comment, user
|
||||
where test_case_comment.author = user.id and case_id = #{caseId}
|
||||
order by test_case_comment.update_time desc
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.track.controller;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseComment;
|
||||
import io.metersphere.track.dto.TestCaseCommentDTO;
|
||||
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
||||
import io.metersphere.track.service.TestCaseCommentService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
public class TestCaseCommentController {
|
||||
|
||||
@Resource
|
||||
TestCaseCommentService testCaseCommentService;
|
||||
private TestCaseCommentService testCaseCommentService;
|
||||
|
||||
@PostMapping("/save")
|
||||
public void saveComment(@RequestBody SaveCommentRequest request) {
|
||||
|
@ -21,7 +21,17 @@ public class TestCaseCommentController {
|
|||
}
|
||||
|
||||
@GetMapping("/list/{caseId}")
|
||||
public List<TestCaseComment> getComments(@PathVariable String caseId) {
|
||||
return testCaseCommentService.getComments(caseId);
|
||||
public List<TestCaseCommentDTO> getCaseComments(@PathVariable String caseId) {
|
||||
return testCaseCommentService.getCaseComments(caseId);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{commentId}")
|
||||
public void deleteComment(@PathVariable String commentId) {
|
||||
testCaseCommentService.delete(commentId);
|
||||
}
|
||||
|
||||
@PostMapping("/edit")
|
||||
public void editComment(@RequestBody SaveCommentRequest request) {
|
||||
testCaseCommentService.edit(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ public class TestCaseReviewController {
|
|||
}
|
||||
|
||||
|
||||
@PostMapping("/get/{reviewId}")
|
||||
@GetMapping("/get/{reviewId}")
|
||||
public TestCaseReview getTestReview(@PathVariable String reviewId) {
|
||||
checkOwnerService.checkTestReviewOwner(reviewId);
|
||||
return testCaseReviewService.getTestReview(reviewId);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package io.metersphere.track.dto;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseComment;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TestCaseCommentDTO extends TestCaseComment {
|
||||
private String authorName;
|
||||
}
|
|
@ -3,21 +3,23 @@ package io.metersphere.track.service;
|
|||
import io.metersphere.base.domain.TestCaseComment;
|
||||
import io.metersphere.base.domain.TestCaseCommentExample;
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.User;
|
||||
import io.metersphere.base.mapper.TestCaseCommentMapper;
|
||||
import io.metersphere.base.mapper.TestCaseMapper;
|
||||
import io.metersphere.base.mapper.TestCaseReviewMapper;
|
||||
import io.metersphere.base.mapper.UserMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseCommentMapper;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.notice.domain.MessageDetail;
|
||||
import io.metersphere.notice.domain.MessageSettingDetail;
|
||||
import io.metersphere.notice.service.DingTaskService;
|
||||
import io.metersphere.notice.service.MailService;
|
||||
import io.metersphere.notice.service.NoticeService;
|
||||
import io.metersphere.notice.service.WxChatTaskService;
|
||||
import io.metersphere.track.dto.TestCaseCommentDTO;
|
||||
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -33,21 +35,19 @@ import java.util.UUID;
|
|||
public class TestCaseCommentService {
|
||||
|
||||
@Resource
|
||||
TestCaseCommentMapper testCaseCommentMapper;
|
||||
private TestCaseCommentMapper testCaseCommentMapper;
|
||||
@Resource
|
||||
private TestCaseReviewMapper testCaseReviewMapper;
|
||||
private MailService mailService;
|
||||
@Resource
|
||||
UserMapper userMapper;
|
||||
private TestCaseMapper testCaseMapper;
|
||||
@Resource
|
||||
MailService mailService;
|
||||
private DingTaskService dingTaskService;
|
||||
@Resource
|
||||
TestCaseMapper testCaseMapper;
|
||||
private WxChatTaskService wxChatTaskService;
|
||||
@Resource
|
||||
DingTaskService dingTaskService;
|
||||
private NoticeService noticeService;
|
||||
@Resource
|
||||
WxChatTaskService wxChatTaskService;
|
||||
@Resource
|
||||
NoticeService noticeService;
|
||||
private ExtTestCaseCommentMapper extTestCaseCommentMapper;
|
||||
|
||||
|
||||
public void saveComment(SaveCommentRequest request) {
|
||||
|
@ -86,21 +86,11 @@ public class TestCaseCommentService {
|
|||
|
||||
}
|
||||
|
||||
public List<TestCaseComment> getComments(String caseId) {
|
||||
TestCaseCommentExample testCaseCommentExample = new TestCaseCommentExample();
|
||||
testCaseCommentExample.setOrderByClause("update_time desc");
|
||||
testCaseCommentExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||
List<TestCaseComment> testCaseComments = testCaseCommentMapper.selectByExampleWithBLOBs(testCaseCommentExample);
|
||||
testCaseComments.forEach(testCaseComment -> {
|
||||
String authorId = testCaseComment.getAuthor();
|
||||
User user = userMapper.selectByPrimaryKey(authorId);
|
||||
String author = user == null ? authorId : user.getName();
|
||||
testCaseComment.setAuthor(author);
|
||||
});
|
||||
return testCaseComments;
|
||||
public List<TestCaseCommentDTO> getCaseComments(String caseId) {
|
||||
return extTestCaseCommentMapper.getCaseComments(caseId);
|
||||
}
|
||||
|
||||
public void deleteComment(String caseId) {
|
||||
public void deleteCaseComment(String caseId) {
|
||||
TestCaseCommentExample testCaseCommentExample = new TestCaseCommentExample();
|
||||
testCaseCommentExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||
testCaseCommentMapper.deleteByExample(testCaseCommentExample);
|
||||
|
@ -118,4 +108,22 @@ public class TestCaseCommentService {
|
|||
context = "测试评审任务通知:" + testCaseComment.getAuthor() + "在" + start + "为" + "'" + testCaseWithBLOBs.getName() + "'" + "添加评论:" + testCaseComment.getDescription();
|
||||
return context;
|
||||
}
|
||||
|
||||
public void delete(String commentId) {
|
||||
checkCommentOwner(commentId);
|
||||
testCaseCommentMapper.deleteByPrimaryKey(commentId);
|
||||
}
|
||||
|
||||
public void edit(SaveCommentRequest request) {
|
||||
checkCommentOwner(request.getId());
|
||||
testCaseCommentMapper.updateByPrimaryKeySelective(request);
|
||||
}
|
||||
|
||||
private void checkCommentOwner(String commentId) {
|
||||
TestCaseComment comment = testCaseCommentMapper.selectByPrimaryKey(commentId);
|
||||
if (!StringUtils.equals(comment.getAuthor(), SessionUtils.getUser().getId())) {
|
||||
MSException.throwException(Translator.get("check_owner_comment"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ public class TestCaseService {
|
|||
example.createCriteria().andCaseIdEqualTo(testCaseId);
|
||||
testPlanTestCaseMapper.deleteByExample(example);
|
||||
testCaseIssueService.delTestCaseIssues(testCaseId);
|
||||
testCaseCommentService.deleteComment(testCaseId);
|
||||
testCaseCommentService.deleteCaseComment(testCaseId);
|
||||
return testCaseMapper.deleteByPrimaryKey(testCaseId);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE `test_plan_test_case` ADD INDEX index_name ( `case_id` );
|
||||
ALTER TABLE `test_case_review_test_case` ADD INDEX index_name ( `case_id` );
|
|
@ -164,6 +164,7 @@ check_owner_test=The current user does not have permission to operate this test
|
|||
check_owner_case=The current user does not have permission to operate this use case
|
||||
check_owner_plan=The current user does not have permission to operate this plan
|
||||
check_owner_review=The current user does not have permission to operate this review
|
||||
check_owner_comment=The current user does not have permission to manipulate this comment
|
||||
upload_content_is_null=Imported content is empty
|
||||
test_plan_notification=Test plan notification
|
||||
task_defect_notification=Task defect notification
|
||||
|
|
|
@ -164,6 +164,7 @@ check_owner_test=当前用户没有操作此测试的权限
|
|||
check_owner_case=当前用户没有操作此用例的权限
|
||||
check_owner_plan=当前用户没有操作此计划的权限
|
||||
check_owner_review=当前用户没有操作此评审的权限
|
||||
check_owner_comment=当前用户没有操作此评论的权限
|
||||
upload_content_is_null=导入内容为空
|
||||
test_plan_notification=测试计划通知
|
||||
task_defect_notification=缺陷任务通知
|
||||
|
|
|
@ -165,6 +165,7 @@ check_owner_test=當前用戶沒有操作此測試的權限
|
|||
check_owner_case=當前用戶沒有操作此用例的權限
|
||||
check_owner_plan=當前用戶沒有操作此計劃的權限
|
||||
check_owner_review=當前用戶沒有操作此評審的權限
|
||||
check_owner_comment=當前用戶沒有操作此評論的權限
|
||||
upload_content_is_null=導入內容為空
|
||||
test_plan_notification=測試計畫通知
|
||||
task_defect_notification=缺陷任務通知
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<div class="comment-list">
|
||||
<review-comment-item v-for="(comment,index) in comments" :key="index" :comment="comment"/>
|
||||
<review-comment-item v-for="(comment,index) in comments"
|
||||
:key="index"
|
||||
:comment="comment"
|
||||
@refresh="refresh"/>
|
||||
<div v-if="comments.length === 0" style="text-align: center">
|
||||
<i class="el-icon-chat-line-square" style="font-size: 15px;color: #8a8b8d;">
|
||||
<span style="font-size: 15px; color: #8a8b8d;">
|
||||
|
@ -56,10 +59,13 @@ export default {
|
|||
}
|
||||
this.result = this.$post('/test/case/comment/save', comment, () => {
|
||||
this.$success(this.$t('test_track.comment.send_success'));
|
||||
this.$emit('getComments');
|
||||
this.refresh();
|
||||
this.textarea = '';
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
this.$emit('getComments');
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -2,30 +2,88 @@
|
|||
<div class="main">
|
||||
<div class="comment-left">
|
||||
<div class="icon-title">
|
||||
{{ comment.author.substring(0, 1) }}
|
||||
{{ comment.authorName.substring(0, 1) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment-right">
|
||||
<span style="font-size: 14px;color: #909399;font-weight: bold">{{ comment.author }}</span>
|
||||
<span style="font-size: 14px;color: #909399;font-weight: bold">{{ comment.authorName }}</span>
|
||||
<span style="color: #8a8b8d; margin-left: 8px; font-size: 12px">
|
||||
{{ comment.createTime | timestampFormatDate }}
|
||||
</span>
|
||||
<span class="comment-delete">
|
||||
<i class="el-icon-edit" style="font-size: 9px;margin-right: 6px;" @click="openEdit"/>
|
||||
<i class="el-icon-close" @click="deleteComment"/>
|
||||
</span>
|
||||
<br/>
|
||||
<div class="comment-desc" style="font-size: 10px;color: #303133">
|
||||
<pre>{{ comment.description }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
:title="$t('commons.edit')"
|
||||
:visible.sync="visible"
|
||||
width="30%"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="false"
|
||||
show-close>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
v-model="description">
|
||||
</el-input>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<ms-dialog-footer
|
||||
@cancel="visible = false"
|
||||
@confirm="editComment"/>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import {getCurrentUser} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "ReviewCommentItem",
|
||||
components: {MsDialogFooter},
|
||||
props: {
|
||||
comment: Object
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
visible: false,
|
||||
description: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
deleteComment() {
|
||||
if (getCurrentUser().id !== this.comment.author) {
|
||||
this.$warning(this.$t('test_track.comment.cannot_delete'));
|
||||
return;
|
||||
}
|
||||
this.$parent.result = this.$get("/test/case/comment/delete/" + this.comment.id, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.$emit("refresh");
|
||||
});
|
||||
},
|
||||
openEdit() {
|
||||
if (getCurrentUser().id !== this.comment.author) {
|
||||
this.$warning(this.$t('test_track.comment.cannot_edit'));
|
||||
return;
|
||||
}
|
||||
this.description = this.comment.description;
|
||||
this.visible = true;
|
||||
},
|
||||
editComment() {
|
||||
this.$post("/test/case/comment/edit", {id: this.comment.id, description: this.description}, () => {
|
||||
this.visible = false;
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.$emit("refresh");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -72,4 +130,10 @@ export default {
|
|||
pre {
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
.comment-delete {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -365,7 +365,7 @@ export default {
|
|||
},
|
||||
getTestReviewById() {
|
||||
if (this.reviewId) {
|
||||
this.$post('/test/case/review/get/' + this.reviewId, {}, response => {
|
||||
this.$get('/test/case/review/get/' + this.reviewId, response => {
|
||||
this.testReview = response.data;
|
||||
this.refreshTestReviewRecent();
|
||||
});
|
||||
|
|
|
@ -853,6 +853,8 @@ export default {
|
|||
relevance_case: "Relevance Case",
|
||||
last_page: "It's the end!",
|
||||
execute_result: "Result",
|
||||
cannot_edit: "Cannot edit this comment!",
|
||||
cannot_delete: "Cannot delete this comment!",
|
||||
},
|
||||
module: {
|
||||
search: "Search module",
|
||||
|
|
|
@ -845,6 +845,8 @@ export default {
|
|||
send: "发送",
|
||||
description_is_null: "评论内容不能为空!",
|
||||
send_success: "评论成功!",
|
||||
cannot_edit: "无法编辑此评论!",
|
||||
cannot_delete: "无法删除此评论!",
|
||||
},
|
||||
review_view: {
|
||||
review: "评审",
|
||||
|
|
|
@ -845,6 +845,8 @@ export default {
|
|||
send: "發送",
|
||||
description_is_null: "評論內容不能為空!",
|
||||
send_success: "評論成功!",
|
||||
cannot_edit: "無法編輯此評論!",
|
||||
cannot_delete: "無法刪除此評論!",
|
||||
},
|
||||
review_view: {
|
||||
review: "評審",
|
||||
|
|
Loading…
Reference in New Issue