feat(用例管理): 新增用例详情执行评论tab
This commit is contained in:
parent
2c0c4c07fa
commit
bcd06b5e27
|
@ -12,7 +12,9 @@ import io.metersphere.functional.excel.domain.FunctionalCaseExcelData;
|
|||
import io.metersphere.functional.mapper.*;
|
||||
import io.metersphere.functional.request.*;
|
||||
import io.metersphere.functional.result.CaseManagementResultCode;
|
||||
import io.metersphere.plan.domain.TestPlanCaseExecuteHistoryExample;
|
||||
import io.metersphere.plan.domain.TestPlanFunctionalCaseExample;
|
||||
import io.metersphere.plan.mapper.TestPlanCaseExecuteHistoryMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.project.domain.*;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
|
@ -166,6 +168,8 @@ public class FunctionalCaseService {
|
|||
@Resource
|
||||
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
||||
@Resource
|
||||
private TestPlanCaseExecuteHistoryMapper testPlanCaseExecuteHistoryMapper;
|
||||
@Resource
|
||||
private FunctionalCaseCommentMapper functionalCaseCommentMapper;
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
|
@ -420,9 +424,12 @@ public class FunctionalCaseService {
|
|||
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||
functionalCaseCommentExample.createCriteria().andCaseIdEqualTo(functionalCaseDetailDTO.getId());
|
||||
long caseComment = functionalCaseCommentMapper.countByExample(functionalCaseCommentExample);
|
||||
long commentCount = caseComment + reviewComment;
|
||||
//获取关联测试计划的执行评论数量
|
||||
TestPlanCaseExecuteHistoryExample testPlanCaseExecuteHistoryExample = new TestPlanCaseExecuteHistoryExample();
|
||||
testPlanCaseExecuteHistoryExample.createCriteria().andCaseIdEqualTo(functionalCaseDetailDTO.getId());
|
||||
long testPlanExecuteComment = testPlanCaseExecuteHistoryMapper.countByExample(testPlanCaseExecuteHistoryExample);
|
||||
long commentCount = caseComment + reviewComment + testPlanExecuteComment;
|
||||
functionalCaseDetailDTO.setCommentCount((int) commentCount);
|
||||
|
||||
//获取变更历史数量数量
|
||||
OperationHistoryExample operationHistoryExample = new OperationHistoryExample();
|
||||
List<String> types = List.of(OperationLogType.ADD.name(), OperationLogType.IMPORT.name(), OperationLogType.UPDATE.name());
|
||||
|
|
|
@ -52,6 +52,7 @@ import {
|
|||
GetDependOnRelationUrl,
|
||||
GetDetailCaseReviewUrl,
|
||||
GetFileIsUpdateUrl,
|
||||
GetPlanExecuteCommentListUrl,
|
||||
GetRecycleCaseListUrl,
|
||||
GetRecycleCaseModulesCountUrl,
|
||||
GetReviewCommentListUrl,
|
||||
|
@ -435,4 +436,9 @@ export function getLinkedCaseTestPlanList(data: TableQueryParams) {
|
|||
return MSR.post<CommonList<AssociateFunctionalCaseItem>>({ url: GetAssociatedTestPlanUrl, data });
|
||||
}
|
||||
|
||||
// 获取执行评论
|
||||
export function getTestPlanExecuteCommentList(caseId: string) {
|
||||
return MSR.get<CommentItem[]>({ url: `${GetPlanExecuteCommentListUrl}/${caseId}` });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -154,3 +154,6 @@ export const associatedProjectOptionsUrl = '/project/list/options';
|
|||
|
||||
// 获取详情已关联测试计划列表
|
||||
export const GetAssociatedTestPlanUrl = '/functional/case/test/has/associate/plan/page';
|
||||
|
||||
// 评审评论
|
||||
export const GetPlanExecuteCommentListUrl = '/functional/case/test/plan/comment';
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<a-radio-group v-model="activeComment" type="button">
|
||||
<a-radio value="caseComment">{{ t('caseManagement.featureCase.caseComment') }}</a-radio>
|
||||
<a-radio value="reviewComment">{{ t('caseManagement.featureCase.reviewComment') }}</a-radio>
|
||||
<!-- <a-radio value="executiveComment">{{ t('caseManagement.featureCase.executiveReview') }}</a-radio> -->
|
||||
<a-radio value="executiveComment">{{ t('caseManagement.featureCase.executiveReview') }}</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -21,13 +21,20 @@
|
|||
</div>
|
||||
|
||||
<!-- 评审评论 -->
|
||||
<div v-show="activeComment === 'reviewComment'" class="flex flex-1 flex-col overflow-hidden">
|
||||
<div
|
||||
v-show="activeComment === 'reviewComment' || activeComment === 'executiveComment'"
|
||||
class="flex flex-1 flex-col overflow-hidden"
|
||||
>
|
||||
<div class="review-history-list">
|
||||
<div v-for="item of reviewCommentList" :key="item.id" class="review-history-list-item">
|
||||
<div class="flex items-center">
|
||||
<MSAvatar :avatar="item.userLogo" />
|
||||
<div class="ml-[8px] flex items-center">
|
||||
<div class="font-medium text-[var(--color-text-1)]">{{ item.userName }}</div>
|
||||
<a-tooltip :content="item.userName" :mouse-enter-delay="300">
|
||||
<div class="one-line-text max-w-[300px] font-medium text-[var(--color-text-1)]">{{
|
||||
item.userName
|
||||
}}</div>
|
||||
</a-tooltip>
|
||||
<a-divider direction="vertical" margin="8px"></a-divider>
|
||||
<div v-if="item.status === 'PASS'" class="flex items-center">
|
||||
<MsIcon type="icon-icon_succeed_filled" class="mr-[4px] text-[rgb(var(--success-6))]" />
|
||||
|
@ -45,24 +52,53 @@
|
|||
<MsIcon type="icon-icon_resubmit_filled" class="mr-[4px] text-[rgb(var(--warning-6))]" />
|
||||
{{ t('caseManagement.caseReview.reReview') }}
|
||||
</div>
|
||||
<div v-if="item.status === 'PASSED'" class="flex items-center">
|
||||
<MsIcon type="icon-icon_succeed_filled" class="mr-[4px] text-[rgb(var(--success-6))]" />
|
||||
{{ t('caseManagement.featureCase.execute.success') }}
|
||||
</div>
|
||||
<div v-if="item.status === 'BLOCKED'" class="flex items-center">
|
||||
<MsIcon type="icon-icon_succeed_filled" class="mr-[4px] text-[rgb(var(--success-6))]" />
|
||||
{{ t('caseManagement.featureCase.execute.blocked') }}
|
||||
</div>
|
||||
<div v-if="item.status === 'FAILED'" class="flex items-center">
|
||||
<MsIcon type="icon-icon_succeed_filled" class="mr-[4px] text-[rgb(var(--success-6))]" />
|
||||
{{ t('caseManagement.featureCase.execute.failed') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="markdown-body" style="margin-left: 48px" v-html="item.contentText"></div>
|
||||
<div class="ml-[48px] mt-[8px] text-[var(--color-text-4)]">
|
||||
<div class="ml-[48px] mt-[8px] flex text-[var(--color-text-4)]">
|
||||
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
<a-tooltip :content="item.reviewName" :mouse-enter-delay="300">
|
||||
<span v-if="item.deleted" class="one-line-text ml-[16px] max-w-[300px] break-words break-all">
|
||||
{{ characterLimit(item.reviewName) }}
|
||||
</span>
|
||||
<div v-if="activeComment === 'reviewComment'">
|
||||
<a-tooltip :content="item.reviewName" :mouse-enter-delay="300">
|
||||
<span v-if="item.deleted" class="one-line-text ml-[16px] max-w-[300px] break-words break-all">
|
||||
{{ characterLimit(item.reviewName) }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-else
|
||||
class="one-line-text ml-[16px] max-w-[300px] cursor-pointer break-words break-all text-[rgb(var(--primary-5))]"
|
||||
@click="review(item)"
|
||||
>
|
||||
{{ characterLimit(item.reviewName) }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
<span
|
||||
v-else
|
||||
class="one-line-text ml-[16px] max-w-[300px] cursor-pointer break-words break-all text-[rgb(var(--primary-5))]"
|
||||
@click="review(item)"
|
||||
>
|
||||
{{ characterLimit(item.reviewName) }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-if="activeComment === 'executiveComment'">
|
||||
<a-tooltip :content="item.testPlanName" :mouse-enter-delay="300">
|
||||
<span v-if="item.deleted" class="one-line-text ml-[16px] max-w-[300px] break-words break-all">
|
||||
{{ characterLimit(item.testPlanName) }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-else
|
||||
class="one-line-text ml-[16px] max-w-[300px] cursor-pointer break-words break-all text-[rgb(var(--primary-5))]"
|
||||
@click="toPlan(item)"
|
||||
>
|
||||
{{ characterLimit(item.testPlanName) }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MsEmpty v-if="reviewCommentList.length === 0" />
|
||||
|
@ -88,15 +124,15 @@
|
|||
editorUploadFile,
|
||||
getCommentList,
|
||||
getReviewCommentList,
|
||||
getTestPlanExecuteCommentList,
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
import { CaseManagementRouteEnum, TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
const router = useRouter();
|
||||
|
@ -133,6 +169,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 初始化执行评论
|
||||
async function initTestPlanExecuteCommentList() {
|
||||
try {
|
||||
const result = await getTestPlanExecuteCommentList(props.caseId);
|
||||
reviewCommentList.value = result;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function getAllCommentList() {
|
||||
switch (activeComment.value) {
|
||||
case 'caseComment':
|
||||
|
@ -144,7 +190,7 @@
|
|||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
break;
|
||||
case 'executiveComment':
|
||||
await initCommentList();
|
||||
await initTestPlanExecuteCommentList();
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
break;
|
||||
default:
|
||||
|
@ -204,6 +250,20 @@
|
|||
});
|
||||
}
|
||||
|
||||
// 去测试计划页面
|
||||
function toPlan(record: CommentItem) {
|
||||
router.push({
|
||||
name: TestPlanRouteEnum.TEST_PLAN_INDEX_DETAIL,
|
||||
query: {
|
||||
...route.query,
|
||||
id: record.testPlanId,
|
||||
},
|
||||
state: {
|
||||
params: JSON.stringify(record.moduleName),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => activeComment.value,
|
||||
(val) => {
|
||||
|
|
|
@ -277,4 +277,7 @@ export default {
|
|||
'caseManagement.featureCase.deleteFileTip':
|
||||
'After deletion, the file cannot be restored. Please operate with caution!',
|
||||
'caseManagement.featureCase.nameNotNull': 'The name can not be null!',
|
||||
'caseManagement.featureCase.execute.success': 'SUCCESS',
|
||||
'caseManagement.featureCase.execute.failed': 'ERROR',
|
||||
'caseManagement.featureCase.execute.blocked': 'BLOCKED',
|
||||
};
|
||||
|
|
|
@ -272,4 +272,7 @@ export default {
|
|||
'caseManagement.featureCase.deleteFile': '确认删除文件 {name} 吗',
|
||||
'caseManagement.featureCase.deleteFileTip': '删除后,文件无法恢复,请谨慎操作!',
|
||||
'caseManagement.featureCase.nameNotNull': '用例名称不能为空!',
|
||||
'caseManagement.featureCase.execute.success': '成功',
|
||||
'caseManagement.featureCase.execute.failed': '失败',
|
||||
'caseManagement.featureCase.execute.blocked': '阻塞',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue