fix(测试跟踪): 测试用例详情页以及测试计划评论,没有进行Markdown渲染

--bug=1023963 --user=陈建星 [测试跟踪] github#22399测试计划中用例展示的评论内容没有进行Markdown渲染 https://www.tapd.cn/55049933/s/1345517
--bug=1023962 --user=陈建星 [测试跟踪] github#22393编辑用例页面, 前置条件和备注没有进行Markdown渲染, 显示的是源码 https://www.tapd.cn/55049933/s/1345518
This commit is contained in:
chenjianxing 2023-03-06 15:41:54 +08:00 committed by jianxing
parent 51cb804905
commit 1db32ded82
10 changed files with 50 additions and 158 deletions

View File

@ -27,7 +27,7 @@
<div class="readonly" v-show="!edit"> <div class="readonly" v-show="!edit">
<div <div
class="text" class="text"
v-if="contentObject.content && contentObject.contentType == 'TEXT'" v-if="contentObject.content && contentObject.contentType === 'TEXT'"
@click="handleReadTextClick" @click="handleReadTextClick"
> >
{{ contentObject.content }} {{ contentObject.content }}
@ -35,7 +35,7 @@
<div <div
class="select" class="select"
v-else-if=" v-else-if="
contentObject.content && contentObject.contentType == 'INPUT' contentObject.content && contentObject.contentType === 'INPUT'
" "
@click="handleReadTextClick" @click="handleReadTextClick"
@mouseenter="mouseEnterEvent" @mouseenter="mouseEnterEvent"
@ -46,7 +46,7 @@
class="tag-wrap" class="tag-wrap"
v-else-if=" v-else-if="
contentObject.content && contentObject.content &&
contentObject.contentType == 'TAG' && contentObject.contentType === 'TAG' &&
Array.isArray(contentObject.content) && Array.isArray(contentObject.content) &&
contentObject.content.length > 0 contentObject.content.length > 0
" "
@ -67,7 +67,7 @@
v-else-if=" v-else-if="
contentObject.content && contentObject.content &&
contentObject.content.demandId && contentObject.content.demandId &&
contentObject.contentType == 'STORY' contentObject.contentType === 'STORY'
" "
@click="handleReadTextClick" @click="handleReadTextClick"
> >
@ -81,7 +81,7 @@
<div <div
class="select" class="select"
v-else-if=" v-else-if="
contentObject.content && contentObject.contentType == 'SELECT' contentObject.content && contentObject.contentType === 'SELECT'
" "
@mouseenter="mouseEnterEvent" @mouseenter="mouseEnterEvent"
> >
@ -90,21 +90,35 @@
<div <div
class="select" class="select"
v-else-if=" v-else-if="
contentObject.content && contentObject.contentType == 'RICHTEXT' contentObject.content && contentObject.contentType === 'RICHTEXT'
" "
@click="handleReadTextClick" @click="handleReadTextClick"
> >
{{ contentObject.content }} <ms-mark-down-text
v-if="contentObject.contentType === 'RICHTEXT'"
class="rich-text"
prop="content"
:disabled="true"
:data="contentObject"/>
</div> </div>
<div <div
v-else-if=" v-else-if="
contentObject.content && contentObject.contentType == 'CUSTOM' contentObject.content && contentObject.contentType === 'CUSTOM'
" "
:class="getCustomComponentType()" :class="getCustomComponentType()"
@click="handleReadTextClick" @click="handleReadTextClick"
@mouseenter="mouseEnterEvent" @mouseenter="mouseEnterEvent"
> >
{{ getCustomText() }} <span v-if="contentObject.content.type !== 'richText'">
{{ getCustomText() }}
</span>
<span v-else>
<ms-mark-down-text
class="rich-text"
prop="defaultValue"
:disabled="true"
:data="contentObject.content"/>
</span>
</div> </div>
<div class="empty" v-else @click="handleReadTextClick"> <div class="empty" v-else @click="handleReadTextClick">
{{ $t("case.none") }} {{ $t("case.none") }}
@ -115,8 +129,10 @@
</template> </template>
<script> <script>
import { getProjectMemberOption } from "metersphere-frontend/src/api/user"; import { getProjectMemberOption } from "metersphere-frontend/src/api/user";
import MsMarkDownText from "@/business/case/components/richtext/MsMarkDownText";
export default { export default {
name: "BaseEditItemComponent", name: "BaseEditItemComponent",
components: {MsMarkDownText},
data() { data() {
return { return {
selfEditable: false, selfEditable: false,
@ -149,7 +165,7 @@ export default {
contentClickEvent: { contentClickEvent: {
type: Boolean, type: Boolean,
default: true, default: true,
}, }
}, },
computed: { computed: {
edit() { edit() {
@ -403,6 +419,20 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/business/style/index.scss"; @import "@/business/style/index.scss";
.rich-text {
border: 0px !important;
box-sizing: border-box;
border-radius: 4px;
box-shadow: none !important;
padding: 0 !important;
}
.rich-text :deep(.v-show-content) {
background-color: #fff !important;
padding: 0 !important;
}
.text { .text {
font-family: "PingFang SC"; font-family: "PingFang SC";
font-style: normal; font-style: normal;

View File

@ -2102,8 +2102,6 @@ export default {
border-bottom: 1px solid #bbbfc4; border-bottom: 1px solid #bbbfc4;
} }
:deep(.v-note-wrapper) { :deep(.v-note-wrapper) {
box-sizing: border-box;
border: 1px solid #bbbfc4 !important;
border-radius: 4px; border-radius: 4px;
box-shadow: none !important; box-shadow: none !important;
} }

View File

@ -840,7 +840,6 @@ export default {
} }
:deep(.v-note-wrapper) { :deep(.v-note-wrapper) {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #bbbfc4 !important;
border-radius: 4px; border-radius: 4px;
box-shadow: none !important; box-shadow: none !important;
} }

View File

@ -126,9 +126,6 @@ export default {
:deep(.v-right-item) { :deep(.v-right-item) {
display: none; display: none;
} }
:deep(.v-note-wrapper:hover) {
border: 1px solid #783887 !important;
}
:deep(.v-note-wrapper .v-note-op) { :deep(.v-note-wrapper .v-note-op) {
height: 34px !important; height: 34px !important;
min-height: 34px !important; min-height: 34px !important;

View File

@ -432,13 +432,9 @@ export default {
} }
:deep(.v-note-wrapper) { :deep(.v-note-wrapper) {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #bbbfc4 !important;
border-radius: 4px; border-radius: 4px;
box-shadow: none !important; box-shadow: none !important;
} }
:deep(.v-note-wrapper:hover) {
border: 1px solid #783887 !important;
}
:deep(.v-note-show) { :deep(.v-note-show) {
min-height: 65px; min-height: 65px;

View File

@ -149,6 +149,7 @@
<el-scrollbar> <el-scrollbar>
<div class="content-container editable-container" v-if="editable"> <div class="content-container editable-container" v-if="editable">
<case-detail-component <case-detail-component
:class="{ 'edit-component' : (editableState || editable) }"
:type="type" :type="type"
:case-id="caseId" :case-id="caseId"
:read-only="readOnly" :read-only="readOnly"
@ -516,6 +517,10 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/business/style/index.scss"; @import "@/business/style/index.scss";
.edit-component :deep(.v-note-wrapper) {
border: 1px solid #bbbfc4 !important;
}
.case-edit-wrap { .case-edit-wrap {
:deep(.el-form-item__content) { :deep(.el-form-item__content) {
line-height: px2rem(32); line-height: px2rem(32);
@ -619,7 +624,6 @@ export default {
} }
:deep(.v-note-wrapper) { :deep(.v-note-wrapper) {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #bbbfc4 !important;
border-radius: 4px; border-radius: 4px;
box-shadow: none !important; box-shadow: none !important;
} }

View File

@ -253,7 +253,6 @@ export default {
@import "@/business/style/index.scss"; @import "@/business/style/index.scss";
.el-button.el-button--default.el-button--small { .el-button.el-button--default.el-button--small {
background: #ffffff; background: #ffffff;
border: 1px solid #783887 !important;
border-radius: 4px; border-radius: 4px;
} }
.relate-container { .relate-container {

View File

@ -53,7 +53,6 @@ export default {
} }
:deep(.v-note-wrapper) { :deep(.v-note-wrapper) {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #bbbfc4 !important;
border-radius: 4px; border-radius: 4px;
box-shadow: none !important; box-shadow: none !important;
} }

View File

@ -18,20 +18,11 @@
<el-link icon="el-icon-close" v-prevent-link-re-click="1300" @click="deleteComment" :disabled="readOnly"/> <el-link icon="el-icon-close" v-prevent-link-re-click="1300" @click="deleteComment" :disabled="readOnly"/>
</span> </span>
<br/> <br/>
<ms-mark-down-text
<div v-if="!isImage" class="comment-desc" style="font-size: 10px;color: #303133"> class="rich-text"
<pre>{{ comment.description }}</pre> prop="description"
</div> :disabled="true"
<div v-if="isImage" class="demo-image__preview"> :data="comment"/>
<pre>{{ imgDescription }}</pre>
<el-image
:z-index="imageIndex"
style="width: 100px; height: 100px;"
fit="contain"
:src="src"
:preview-src-list="srcList">
</el-image>
</div>
</div> </div>
<el-dialog :visible.sync="visible" <el-dialog :visible.sync="visible"
@ -80,11 +71,9 @@ export default {
return { return {
visible: false, visible: false,
imgDescription: '', imgDescription: '',
imageIndex: 99999,
originDesc: '', originDesc: '',
src: "", src: "",
srcList: [], srcList: [],
imgNameList: [],
description: "", description: "",
imageMatchPattern: "(\\!\\[)\\S+]\\(\\S+\\)", imageMatchPattern: "(\\!\\[)\\S+]\\(\\S+\\)",
toolbars: { toolbars: {
@ -124,22 +113,12 @@ export default {
} }
} }
}, },
computed: {
isImage() {
return this.checkImage(this.comment.description);
}
},
methods: { methods: {
deleteComment() { deleteComment() {
if (getCurrentUser().id !== this.comment.author) { if (getCurrentUser().id !== this.comment.author) {
this.$warning(this.$t('test_track.comment.cannot_delete')); this.$warning(this.$t('test_track.comment.cannot_delete'));
return; return;
} }
if (this.imgNameList.length > 0) {
this.imgNameList.forEach(imgName => {
deleteMarkDownImgByName(imgName);
});
}
this.$get(this.apiUrl + "/comment/delete/" + this.comment.id) this.$get(this.apiUrl + "/comment/delete/" + this.comment.id)
.then(() => { .then(() => {
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
@ -166,107 +145,6 @@ export default {
}, },
handleClose() { handleClose() {
this.comment.description = this.originDesc; this.comment.description = this.originDesc;
},
checkImage() {
this.srcList = [];
let param = this.comment.description;
let returnFlag = false;
if (param) {
let message = param + "";
let matchIndex = message.indexOf("](/resource/md/get");
if (matchIndex > 0) {
let messageSplitArr = message.split("](/resource/md/get");
for (let itemIndex = 0; itemIndex < messageSplitArr.length; itemIndex++) {
let itemStr = messageSplitArr[itemIndex];
let picNameIndex = itemStr.indexOf("![");
if (picNameIndex < 0) {
let endUrlIndex = itemStr.indexOf(")");
if (endUrlIndex > 0) {
let itemStrArr = itemStr.substr(0, endUrlIndex);
//if(imgNameList.)
if (this.imgNameList.indexOf(itemStrArr) < 0) {
this.imgNameList.push(itemStrArr);
}
let imgUrl = "/resource/md/get" + itemStrArr;
this.src = imgUrl;
if (this.srcList.indexOf(itemStrArr) < 0) {
this.srcList.push(imgUrl);
}
if (endUrlIndex !== itemStr.length - 1) {
let inputStr = itemStr.substr(endUrlIndex + 1, itemStr.length - 1);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
} else {
this.imgDescription = "\n" + inputStr;
}
}
if (endUrlIndex !== itemStr.length - 1) {
let inputStr = itemStr.substr(endUrlIndex + 1, itemStr.length - 1);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
} else {
this.imgDescription = "\n" + inputStr;
}
}
}
} else {
let inputStr = itemStr.substr(0, picNameIndex);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
} else {
this.imgDescription = "\n" + inputStr;
}
}
}
} else {
let imgUrlIndex = message.indexOf("](http");
if (imgUrlIndex > 0) {
let imgUrlSplitArr = message.split("](http");
for (let itemIndex = 0; itemIndex < imgUrlSplitArr.length; itemIndex++) {
let itemStr = imgUrlSplitArr[itemIndex];
let picNameIndex = itemStr.indexOf("![");
if (picNameIndex < 0) {
let endUrlIndex = itemStr.indexOf(")");
if (endUrlIndex > 0) {
let itemStrArr = itemStr.substr(0, endUrlIndex);
//if(imgNameList.)
if (this.imgNameList.indexOf(itemStrArr) < 0) {
this.imgNameList.push(itemStrArr);
}
let imgUrl = "http" + itemStrArr;
this.src = imgUrl;
if (this.srcList.indexOf(itemStrArr) < 0) {
this.srcList.push(imgUrl);
}
}
} else {
let inputStr = itemStr.substr(0, picNameIndex);
if (this.imgDescription === "") {
this.imgDescription = inputStr;
} else {
this.imgDescription = "\n" + inputStr;
}
}
}
}
}
if (this.srcList.length > 0) {
returnFlag = true;
}
}
return returnFlag;
},
checkByUrls(url) {
let checkResultFlag = false;
if (this.imgNameList.length > 0) {
this.imgNameList.forEach(imgName => {
if (imgName === url) {
checkResultFlag = true;
}
});
}
return checkResultFlag;
} }
} }
} }
@ -304,13 +182,6 @@ export default {
font-size: 14px; font-size: 14px;
} }
.comment-desc {
overflow-wrap: break-word;
word-break: break-all;
border-bottom: 1px solid #ced3de;
}
pre { pre {
margin: 0 0; margin: 0 0;
white-space: pre-wrap; white-space: pre-wrap;

View File

@ -120,7 +120,6 @@ export default {
width: 30px !important; width: 30px !important;
height: 30px !important; height: 30px !important;
background: #FFFFFF !important; background: #FFFFFF !important;
border: 1px solid #BBBFC4 !important;
border-radius: 4px !important; border-radius: 4px !important;
padding: 5px 4px 4px 3px !important; padding: 5px 4px 4px 3px !important;
} }