Merge pull request #8754 from metersphere/pr@dev@fix_uploadissueimage

fix: 连续上传缺陷图片显示 bug
This commit is contained in:
zhangdahai112 2021-12-22 21:01:34 +08:00 committed by GitHub
commit 744308655e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 142 additions and 91 deletions

View File

@ -29,7 +29,7 @@ public class IssueCommentController {
@PostMapping("/save")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_REVIEW_READ_COMMENT)
@SendNotice(taskType = NoticeConstants.TaskType.DEFECT_TASK, target = "#targetClass.get(#request.issuesId)", targetClass = IssuesService.class,
event = NoticeConstants.Event.COMMENT, mailTemplate = "track/IssuesCommentUpdate", subject = "缺陷评论更新通知")
event = NoticeConstants.Event.COMMENT, mailTemplate = "track/IssuesCommentUpdate", subject = "缺陷")
public IssueComment saveComment(@RequestBody IssuesRelevanceRequest request) {
request.setId(UUID.randomUUID().toString());
return issueCommentService.saveComment(request);

View File

@ -10,7 +10,7 @@
:key="index"
:comment="comment"
:read-only="readOnly"
@refresh="getComments()"/>
@refresh="getComments()" api-url="/test/case"/>
<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;">

View File

@ -115,7 +115,7 @@
<review-comment-item v-for="(comment,index) in comments"
:key="index"
:comment="comment"
@refresh="getComments"/>
@refresh="getComments" api-url="/test/case"/>
<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;">

View File

@ -102,7 +102,7 @@
<review-comment-item v-for="(comment,index) in comments"
:key="index"
:comment="comment"
@refresh="getComments" :disabled="true"/>
@refresh="getComments" :disabled="true" api-url="/test/case"/>
<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;">

View File

@ -88,7 +88,7 @@ export default {
}
this.result = this.$post('/issues/comment/save', comment, () => {
this.$success(this.$t('test_track.comment.send_success'));
this.refresh(comment.IssueId);
this.refresh(comment.issuesId);
this.from.description = '';
this.dialogTableVisible = false;
});

View File

@ -29,10 +29,10 @@ export default {
}
},
methods: {
open(data) {
open(data, type) {
this.visible = true;
this.$nextTick(() => {
this.$refs.issueEditDetail.open(data);
this.$refs.issueEditDetail.open(data, type);
})
},
handleClose() {

View File

@ -235,8 +235,9 @@ export default {
},
},
methods: {
open(data) {
open(data, type) {
this.result.loading = true;
this.type = type;
this.$nextTick(() => {
getIssuePartTemplateWithProject((template, project) => {
this.currentProject = project;
@ -244,17 +245,18 @@ export default {
});
});
if(data&&data.id){
if (data && data.id) {
this.$get('/issues/follow/' + data.id, response => {
this.form.follows = response.data;
for (let i = 0; i < response.data.length; i++) {
if(response.data[i]===this.currentUser().id){
if (response.data[i] === this.currentUser().id) {
this.showFollow = true;
break;
}
}
})
}else {
} else {
this.issueId = null;
this.form.follows = [];
}
},
@ -325,6 +327,7 @@ export default {
}
}
this.customFieldForm = parseCustomField(this.form, this.issueTemplate, this.customFieldRules);
this.comments = [];
this.$nextTick(() => {
if (this.$refs.testCaseIssueList) {
this.$refs.testCaseIssueList.initTableData();
@ -422,6 +425,10 @@ export default {
}
},
openComment() {
if (!this.issueId) {
this.$warning(this.$t('test_track.issue.save_before_open_comment'));
return;
}
this.$refs.issueComment.open();
},
getComments() {

View File

@ -295,17 +295,17 @@ export default {
},
handleEdit(data) {
this.$refs.issueEdit.open(data);
this.$refs.issueEdit.open(data, 'edit');
},
handleCreate() {
this.$refs.issueEdit.open();
this.$refs.issueEdit.open(null, 'add');
},
handleCopy(data) {
let copyData = {};
Object.assign(copyData, data);
copyData.id = null;
copyData.name = data.name + '_copy';
this.$refs.issueEdit.open(copyData);
this.$refs.issueEdit.open(copyData, 'copy');
},
handleDelete(data) {
this.page.result = this.$get('issues/delete/' + data.id, () => {

View File

@ -19,46 +19,45 @@
</el-button>
</span>
<span class="comment-delete">
<el-link icon="el-icon-edit" v-if="!isImage" style="font-size: 9px;margin-right: 6px;" @click="openEdit" :disabled="readOnly"/>
<el-link icon="el-icon-edit" style="font-size: 9px;margin-right: 6px;" @click="openEdit" :disabled="readOnly"/>
<el-link icon="el-icon-close" @click="deleteComment" :disabled="readOnly"/>
</span>
<br/>
<!-- <div class="comment-desc" style="font-size: 10px;color: #303133">-->
<!-- <pre>{{ comment.description }}</pre>-->
<!-- </div>-->
<div v-if="!isImage" class="comment-desc" style="font-size: 10px;color: #303133">
<div v-if="!isImage" class="comment-desc" style="font-size: 10px;color: #303133">
<pre>{{ comment.description }}</pre>
</div>
<div v-if="isImage" class="demo-image__preview">
<pre>{{ imgDescription }}</pre>
<el-image
:z-index="imageIndex"
style="width: 100px; height: 100px;"
fit="contain"
:src="src"
:preview-src-list="srcList">
:z-index="imageIndex"
style="width: 100px; height: 100px;"
fit="contain"
:src="src"
:preview-src-list="srcList">
</el-image>
</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 :visible.sync="visible"
:title="$t('commons.edit')"
:destroy-on-close="true"
:close-on-click-modal="false"
append-to-body>
<div>
<div class="editors_div_style">
<div id="editorsDiv">
<ms-mark-down-text prop="description" :data="comment" :toolbars="toolbars"/>
</div>
</div>
<div>
<el-button type="primary" size="mini" class="send-btn" @click="editComment">
{{ $t('test_track.comment.send') }}
</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
@ -66,10 +65,11 @@
<script>
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import {getCurrentUser} from "@/common/js/utils";
import MsMarkDownText from "@/business/components/track/case/components/MsMarkDownText";
export default {
name: "ReviewCommentItem",
components: {MsDialogFooter},
components: {MsDialogFooter, MsMarkDownText},
props: {
comment: Object,
readOnly: {
@ -83,16 +83,51 @@ export default {
return {
visible: false,
imgDescription: "",
imageIndex:99999,
src:"",
srcList:[],
imgNameList:[],
imageIndex: 99999,
src: "",
srcList: [],
imgNameList: [],
description: "",
imageMatchPattern:"(\\!\\[)\\S+]\\(\\S+\\)",
imageMatchPattern: "(\\!\\[)\\S+]\\(\\S+\\)",
toolbars: {
bold: false, //
italic: false, //
header: false, //
underline: false, // 线
strikethrough: false, // 线
mark: false, //
superscript: false, //
subscript: false, //
quote: false, //
ol: false, //
ul: false, //
link: false, //
imagelink: true, //
code: false, // code
table: false, //
fullscreen: false, //
readmodel: false, //
htmlcode: false, // html
help: false, //
/* 1.3.5 */
undo: false, //
redo: false, //
trash: false, //
save: false, // eventssave
/* 1.4.2 */
navigation: false, //
/* 2.1.8 */
alignleft: false, //
aligncenter: false, //
alignright: false, //
/* 2.2.1 */
subfield: false, //
preview: false, //
}
}
},
computed:{
isImage(){
computed: {
isImage() {
return this.checkImage(this.comment.description);
}
},
@ -102,7 +137,7 @@ export default {
this.$warning(this.$t('test_track.comment.cannot_delete'));
return;
}
if(this.imgNameList.length > 0){
if (this.imgNameList.length > 0) {
this.imgNameList.forEach(imgName => {
this.$get('/resource/md/delete/' + imgName);
});
@ -121,90 +156,91 @@ export default {
this.visible = true;
},
editComment() {
this.$post(this.apiUrl + "/comment/edit", {id: this.comment.id, description: this.description}, () => {
this.$post(this.apiUrl + "/comment/edit", {id: this.comment.id, description: this.comment.description}, () => {
this.visible = false;
this.$success(this.$t('commons.modify_success'));
this.$emit("refresh");
});
},
checkImage(){
checkImage() {
this.srcList = [];
let param = this.comment.description;
let returnFlag = false;
if(param){
let message = param+"";
if (param) {
let message = param + "";
let matchIndex = message.indexOf("](/resource/md/get/");
if(matchIndex > 0){
if (matchIndex > 0) {
let messageSplitArr = message.split("](/resource/md/get/");
for(let itemIndex = 0;itemIndex < messageSplitArr.length; itemIndex ++){
for (let itemIndex = 0; itemIndex < messageSplitArr.length; itemIndex++) {
let itemStr = messageSplitArr[itemIndex];
let picNameIndex = itemStr.indexOf("![");
if( picNameIndex < 0){
if (picNameIndex < 0) {
let endUrlIndex = itemStr.indexOf(")");
if( endUrlIndex > 0){
let itemStrArr = itemStr.substr(0,endUrlIndex);
if (endUrlIndex > 0) {
let itemStrArr = itemStr.substr(0, endUrlIndex);
//if(imgNameList.)
if(this.imgNameList.indexOf(itemStrArr) < 0){
if (this.imgNameList.indexOf(itemStrArr) < 0) {
this.imgNameList.push(itemStrArr);
}
let imgUrl = "/resource/md/get/"+itemStrArr;
let imgUrl = "/resource/md/get/" + itemStrArr;
this.src = imgUrl;
if(this.srcList.indexOf(itemStrArr) < 0){
if (this.srcList.indexOf(itemStrArr) < 0) {
this.srcList.push(imgUrl);
}
}
}else{
let inputStr = itemStr.substr(0,picNameIndex);
if(this.imgDescription === ""){
} else {
let inputStr = itemStr.substr(0, picNameIndex);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
}else {
} else {
this.imgDescription = "\n" + inputStr;
}
}
}
}else{
} else {
let imgUrlIndex = message.indexOf("](http");
if(imgUrlIndex > 0){
if (imgUrlIndex > 0) {
let imgUrlSplitArr = message.split("](http");
for(let itemIndex = 0;itemIndex < imgUrlSplitArr.length; itemIndex ++){
for (let itemIndex = 0; itemIndex < imgUrlSplitArr.length; itemIndex++) {
let itemStr = imgUrlSplitArr[itemIndex];
let picNameIndex = itemStr.indexOf("![");
if( picNameIndex < 0){
if (picNameIndex < 0) {
let endUrlIndex = itemStr.indexOf(")");
if( endUrlIndex > 0){
let itemStrArr = itemStr.substr(0,endUrlIndex);
if (endUrlIndex > 0) {
let itemStrArr = itemStr.substr(0, endUrlIndex);
//if(imgNameList.)
if(this.imgNameList.indexOf(itemStrArr) < 0){
if (this.imgNameList.indexOf(itemStrArr) < 0) {
this.imgNameList.push(itemStrArr);
}
let imgUrl = "http"+itemStrArr;
let imgUrl = "http" + itemStrArr;
this.src = imgUrl;
if(this.srcList.indexOf(itemStrArr) < 0){
if (this.srcList.indexOf(itemStrArr) < 0) {
this.srcList.push(imgUrl);
}
}
}else{
let inputStr = itemStr.substr(0,picNameIndex);
if(this.imgDescription === ""){
} else {
let inputStr = itemStr.substr(0, picNameIndex);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
}else {
} else {
this.imgDescription = "\n" + inputStr;
}
}
}
}
}
if(this.srcList.length > 0){
if (this.srcList.length > 0) {
returnFlag = true;
}
}
return returnFlag;
},
checkByUrls(url){
checkByUrls(url) {
let checkResultFlag = false;
if(this.imgNameList.length > 0){
if (this.imgNameList.length > 0) {
this.imgNameList.forEach(imgName => {
if(imgName === url){
if (imgName === url) {
checkResultFlag = true;
}
});
@ -269,6 +305,11 @@ pre {
}
/deep/ .el-button--mini, .el-button--mini.is-round {
padding: 4px 9px;
padding: 7px 15px;
}
.send-btn {
margin-top: 5px;
width: 100%;
}
</style>

View File

@ -2085,7 +2085,7 @@ export default {
comment: {
no_comment: "No Comment",
send_comment: "Post a comment (Ctrl + Enter to send)",
send: "Send",
send: "Confirm",
description_is_null: "Comment content cannot be empty!",
send_success: "Comment successful!",
},
@ -2236,7 +2236,8 @@ export default {
third_party_integrated: "Third-party Platform Integrated",
use_third_party: "Enable Jira Issue Template",
update_third_party_bugs: "Update the defects of third-party platforms",
sync_bugs: "Synchronization Issue"
sync_bugs: "Synchronization Issue",
save_before_open_comment: "Please save issue before comment",
},
report: {
name: "Test Plan Report",

View File

@ -2089,7 +2089,7 @@ export default {
comment: {
no_comment: "暂无评论",
send_comment: "发表评论Ctrl+Enter发送",
send: "发送",
send: "确定",
description_is_null: "评论内容不能为空!",
send_success: "评论成功!",
cannot_edit: "无法编辑此评论!",
@ -2240,7 +2240,8 @@ export default {
third_party_integrated: "集成第三方平台",
use_third_party: "使用 Jira 缺陷模板",
update_third_party_bugs: "更新第三方平台的缺陷",
sync_bugs: "同步缺陷"
sync_bugs: "同步缺陷",
save_before_open_comment: "请先保存缺陷再添加评论",
},
report: {
name: "测试计划报告",

View File

@ -2089,7 +2089,7 @@ export default {
comment: {
no_comment: "暫無評論",
send_comment: "發表評論Ctrl+Enter發送",
send: "發送",
send: "確定",
description_is_null: "評論內容不能為空!",
send_success: "評論成功!",
cannot_edit: "無法編輯此評論!",
@ -2240,7 +2240,8 @@ export default {
third_party_integrated: "集成第三方平臺",
use_third_party: "使用 Jira 缺陷模板",
update_third_party_bugs: "更新第三方平臺的缺陷",
sync_bugs: "同步缺陷"
sync_bugs: "同步缺陷",
save_before_open_comment: "請先保存缺陷再添加評論",
},
report: {
name: "測試計劃報告",