fix(用例管理): 代码回退菜单恢复

This commit is contained in:
xinxin.wu 2024-02-28 21:21:11 +08:00 committed by 刘瑞斌
parent a7a855dfa8
commit 4d832ce503
18 changed files with 336 additions and 159 deletions

View File

@ -295,8 +295,11 @@ export function createCommentList(data: CommentParams) {
}
// 编辑评论
export function updateCommentList(data: CommentParams) {
return MSR.post({ url: UpdateCommentItemUrl, data });
export function addOrUpdateCommentList(data: CommentParams) {
if (data.fetchType === 'UPDATE') {
return MSR.post({ url: UpdateCommentItemUrl, data });
}
return MSR.post({ url: CreateCommentItemUrl, data });
}
// 删除评论

View File

@ -1,8 +1,8 @@
<template>
<div class="flex flex-row gap-[8px]">
<div class="p-1"> <MsAvatar avatar="word" /></div>
<div class="p-1"> <MsAvatar :avatar="props.element.commentUserInfos[0].avatar" /></div>
<div class="flex w-full flex-col">
<div class="font-medium text-[var(--color-text-1)]">{{ props.element.createUser }}</div>
<div class="font-medium text-[var(--color-text-1)]">{{ props.element.commentUserInfos[0].name }}</div>
<div v-dompurify-html="props.element.content" class="markdown-body mt-[4px]"></div>
<div class="mb-4 mt-[16px] flex flex-row items-center">

View File

@ -26,6 +26,7 @@ export default {
'menu.apiTest': 'API Test',
'menu.apiTest.debug': 'API debug',
'menu.apiTest.management': 'API Management',
'menu.apiTest.report': 'API Report',
'menu.uiTest': 'UI Test',
'menu.performanceTest': 'Performance Test',
'menu.projectManagement': 'Project',

View File

@ -26,6 +26,7 @@ export default {
'menu.apiTest': '接口测试',
'menu.apiTest.debug': '接口调试',
'menu.apiTest.management': '接口管理',
'menu.apiTest.report': '接口报告',
'menu.uiTest': 'UI测试',
'menu.workstation': '工作台',
'menu.loadTest': '性能测试',

View File

@ -43,6 +43,16 @@ const ApiTest: AppRouteRecordRaw = {
isTopMenu: true,
},
},
{
path: 'report',
name: ApiTestRouteEnum.API_TEST_REPORT,
component: () => import('@/views/api-test/report/index.vue'),
meta: {
locale: 'menu.apiTest.report',
roles: ['*'],
isTopMenu: true,
},
},
],
};

View File

@ -0,0 +1,22 @@
<template>
<!-- <MsCard class="mb-[16px]" :title="props.title" hide-back hide-footer auto-height no-content-padding no-bottom-radius>
<a-tabs v-model:active-key="innerTab" class="no-content">
<a-tab-pane v-for="item of tabList" :key="item.key" :title="item.title" />
</a-tabs>
</MsCard> -->
<div></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import MsCard from '@/components/pure/ms-card/index.vue';
const tabList = [
{
value: '',
},
];
</script>
<style scoped></style>

View File

@ -0,0 +1 @@
export default {};

View File

@ -0,0 +1,85 @@
export default {
'apiTestManagement.newApi': '新建接口',
'apiTestManagement.importApi': '导入接口',
'apiTestManagement.fileImport': '文件导入',
'apiTestManagement.timeImport': '定时导入',
'apiTestManagement.addSubModule': '添加子模块',
'apiTestManagement.allApi': '全部接口',
'apiTestManagement.searchTip': '请输入模块/接口名称',
'apiTestManagement.moveSearchTip': '请输入模块名称搜索',
'apiTestManagement.noMatchModule': '暂无匹配的模块/接口',
'apiTestManagement.execute': '执行',
'apiTestManagement.share': '分享 API',
'apiTestManagement.shareModule': '分享模块',
'apiTestManagement.doc': '文档',
'apiTestManagement.closeAll': '关闭全部tab',
'apiTestManagement.closeOther': '关闭其他tab',
'apiTestManagement.showSubdirectory': '显示子目录用例',
'apiTestManagement.searchPlaceholder': '输入 ID/名称/api路径搜索',
'apiTestManagement.apiName': '接口名称',
'apiTestManagement.apiType': '请求类型',
'apiTestManagement.apiStatus': '状态',
'apiTestManagement.responsiblePerson': '责任人',
'apiTestManagement.path': '路径',
'apiTestManagement.version': '版本',
'apiTestManagement.createTime': '创建时间',
'apiTestManagement.updateTime': '更新时间',
'apiTestManagement.deprecate': '已废弃',
'apiTestManagement.processing': '进行中',
'apiTestManagement.debugging': '联调中',
'apiTestManagement.done': '已完成',
'apiTestManagement.deleteApiTipTitle': '确认删除 {name} 吗?',
'apiTestManagement.deleteApiTip': '删除后,接口将放入回收站,可在回收站内进行数据恢复',
'apiTestManagement.batchDeleteApiTip': '确认删除已选中的 {count} 个接口吗?',
'apiTestManagement.batchModalSubTitle': '(已选 {count} 个接口)',
'apiTestManagement.chooseAttr': '选择属性',
'apiTestManagement.attrRequired': '属性不能为空',
'apiTestManagement.batchUpdate': '批量更新为',
'apiTestManagement.valueRequired': '属性值不能为空',
'apiTestManagement.batchMoveConfirm': '移动至所选模块',
'apiTestManagement.belongModule': '所属模块',
'apiTestManagement.importMode': '导入模式',
'apiTestManagement.importModeTip1': '覆盖:',
'apiTestManagement.importModeTip2': '1.同一接口请求类型+路径一致,请求参数内容不一致则覆盖',
'apiTestManagement.importModeTip3': '2.同一接口请求类型+路径一致,请求参数内容一致不做变更',
'apiTestManagement.importModeTip4': '3.非同一接口,请求类型+路径一致,则新增',
'apiTestManagement.importModeTip5': '不覆盖:',
'apiTestManagement.importModeTip6': '1.同一接口请求类型+路径一致,则不做变更',
'apiTestManagement.importModeTip7': '2.非同一接口请求类型+路径一致,则新增',
'apiTestManagement.cover': '覆盖',
'apiTestManagement.uncover': '不覆盖',
'apiTestManagement.moreSetting': '更多设置',
'apiTestManagement.importType': '导入方式',
'apiTestManagement.urlImport': 'URL 导入',
'apiTestManagement.syncImportCase': '同步导入接口用例',
'apiTestManagement.syncUpdateDirectory': '同步更新接口所在目录',
'apiTestManagement.importSwaggerFileTip1': '支持 Swagger 3.0 版本的 json 文件,',
'apiTestManagement.importSwaggerFileTip2': '2.0 的文件建议自行在官网转换成 3.0 再进行导入',
'apiTestManagement.importSwaggerFileTip3': ',大小不超过 50M',
'apiTestManagement.urlImportPlaceholder': '请输入OpenAPI/Swagger URL',
'apiTestManagement.swaggerURLRequired': 'SwaggerURL 不能为空',
'apiTestManagement.basicAuth': 'Basic Auth 认证',
'apiTestManagement.account': '账号',
'apiTestManagement.accountRequired': '账号不能为空',
'apiTestManagement.password': '密码',
'apiTestManagement.passwordRequired': '密码不能为空',
'apiTestManagement.taskName': '任务名称',
'apiTestManagement.taskNamePlaceholder': '请输入任务名称',
'apiTestManagement.taskNameRequired': '任务名称不能为空',
'apiTestManagement.syncFrequency': '同步频率',
'apiTestManagement.timeTaskList': '定时任务列表',
'apiTestManagement.timeTaskHour': '(每小时)',
'apiTestManagement.timeTaskSixHour': '(每 6 小时)',
'apiTestManagement.timeTaskTwelveHour': '(每 12 小时)',
'apiTestManagement.timeTaskDay': '(每天)',
'apiTestManagement.customFrequency': '自定义频率',
'apiTestManagement.case': '用例',
'apiTestManagement.definition': '定义',
'apiTestManagement.addDependency': '添加依赖关系',
'apiTestManagement.preDependency': '前置依赖',
'apiTestManagement.addPreDependency': '添加前置依赖',
'apiTestManagement.postDependency': '后置依赖',
'apiTestManagement.addPostDependency': '添加后置依赖',
'apiTestManagement.saveAsCase': '保存为新用例',
'apiTestManagement.apiNamePlaceholder': '请输入接口名称',
};

View File

@ -92,16 +92,9 @@
height: 'calc(100% - 86px)',
}"
>
<MsSplitBox
ref="wrapperRef"
class="h-[calc(100% - 78px)]"
expand-direction="right"
:max="0.7"
:min="0.7"
:size="900"
>
<MsSplitBox :size="0.7" :max="0.9" :min="0.7" direction="horizontal" expand-direction="right">
<template #first>
<div class="leftWrapper">
<div class="leftWrapper h-full">
<div class="header h-[50px]">
<a-menu mode="horizontal" :default-selected-keys="[activeTab || 'detail']" @menu-item-click="clickMenu">
<a-menu-item key="detail">{{ t('caseManagement.featureCase.detail') }} </a-menu-item>
@ -121,29 +114,48 @@
>
</a-menu>
</div>
<div class="leftContent mt-4 px-4">
<TabDetail
v-if="activeTab === 'detail'"
ref="tabDetailRef"
:form="detailInfo"
:allow-edit="true"
:form-rules="formItem"
:active-tab="activeTab"
@update-success="updateSuccess"
/>
<TabCaseTable v-show="activeTab === 'case'" :case-id="props.detailId" />
<TabDemand v-show="activeTab === 'requirement'" :case-id="props.detailId" />
<TabDefect v-show="activeTab === 'bug'" :case-id="props.detailId" />
<TabDependency v-show="activeTab === 'dependency'" :case-id="props.detailId" />
<TabCaseReview v-show="activeTab === 'caseReview'" :case-id="props.detailId" />
<TabTestPlan v-show="activeTab === 'testPlan'" :active-tab="activeTab" />
<TabComment v-if="activeTab === 'comments'" ref="commentRef" :case-id="props.detailId" />
<TabChangeHistory v-show="activeTab === 'changeHistory'" :case-id="props.detailId" />
</div>
<keep-alive>
<div class="leftContent mt-4 px-4">
<template v-if="activeTab === 'detail'">
<TabDetail
ref="tabDetailRef"
:form="detailInfo"
:allow-edit="true"
:form-rules="formItem"
:active-tab="activeTab"
@update-success="updateSuccess"
/>
</template>
<template v-if="activeTab === 'requirement'">
<TabDemand :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'case'">
<TabCaseTable :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'bug'">
<TabDefect :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'dependency'">
<TabDependency :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'caseReview'">
<TabCaseReview :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'testPlan'">
<TabTestPlan :active-tab="activeTab" />
</template>
<template v-if="activeTab === 'comments'">
<TabComment ref="commentRef" :active-tab="activeTab" :case-id="props.detailId" />
</template>
<template v-if="activeTab === 'changeHistory'">
<TabChangeHistory :active-tab="activeTab" :case-id="props.detailId" />
</template>
</div>
</keep-alive>
</div>
</template>
<template #second>
<div class="rightWrapper p-[24px]">
<div class="rightWrapper h-full p-[24px]">
<div class="mb-4 font-medium">{{ t('caseManagement.featureCase.basicInfo') }}</div>
<div class="baseItem">
<span class="label"> {{ t('caseManagement.featureCase.tableColumnModule') }}</span>
@ -349,7 +361,16 @@
// count
function setCount(detail: DetailCase) {
const { bugCount, caseCount, caseReviewCount, demandCount, relateEdgeCount, testPlanCount, commentCount, historyCount } = detail;
const {
bugCount,
caseCount,
caseReviewCount,
demandCount,
relateEdgeCount,
testPlanCount,
commentCount,
historyCount,
} = detail;
const countMap: Record<string, any> = {
case: caseCount,
dependency: relateEdgeCount,
@ -358,7 +379,7 @@
bug: bugCount,
requirement: demandCount,
comments: commentCount,
changeHistory: historyCount
changeHistory: historyCount,
};
featureCaseStore.initCountMap(countMap);
}
@ -611,9 +632,10 @@
}
}
);
provide('activeTab', activeTab.value);
onMounted(() => {
// settingDrawerRef.value.getTabModule();
settingDrawerRef.value.getTabModule();
});
</script>

View File

@ -128,8 +128,9 @@
const props = defineProps<{
caseId: string;
activeTab: string;
}>();
const activeTab = computed(() => featureCaseStore.activeTab);
// const activeTab = computed(() => featureCaseStore.activeTab);
const showType = ref('link');
const keyword = ref<string>('');
@ -322,18 +323,18 @@
}
);
watch(
() => activeTab.value,
(val) => {
if (val === 'bug') {
getFetch();
}
}
);
// watch(
// () => activeTab.value,
// (val) => {
// if (val === 'bug') {
// getFetch();
// }
// }
// );
// onMounted(() => {
// getFetch();
// });
onMounted(() => {
getFetch();
});
</script>
<style scoped></style>

View File

@ -273,20 +273,20 @@
}
const activeTab = computed(() => featureCaseStore.activeTab);
watch(
() => activeTab.value,
(val) => {
if (val === 'case') {
getEnabledModules();
getFetch();
}
}
);
// watch(
// () => activeTab.value,
// (val) => {
// if (val === 'case') {
// getEnabledModules();
// getFetch();
// }
// }
// );
// onMounted(async () => {
// getEnabledModules();
// getFetch();
// });
onMounted(async () => {
getEnabledModules();
getFetch();
});
</script>
<style scoped></style>

View File

@ -48,11 +48,12 @@
import debounce from 'lodash-es/debounce';
const featureCaseStore = useFeatureCaseStore();
const activeTab = computed(() => featureCaseStore.activeTab);
// const activeTab = computed(() => featureCaseStore.activeTab);
const { t } = useI18n();
const props = defineProps<{
caseId: string; // id
activeTab: string;
}>();
const keyword = ref<string>('');
@ -114,18 +115,18 @@
initData();
}, 100);
watch(
() => activeTab.value,
(val) => {
if (val === 'caseReview') {
initData();
}
}
);
// watch(
// () => activeTab.value,
// (val) => {
// if (val === 'caseReview') {
// initData();
// }
// }
// );
// onMounted(() => {
// initData();
// });
onMounted(() => {
initData();
});
</script>
<style scoped></style>

View File

@ -95,13 +95,14 @@
const appStore = useAppStore();
const featureCaseStore = useFeatureCaseStore();
const activeTab = computed(() => featureCaseStore.activeTab);
// const activeTab = computed(() => featureCaseStore.activeTab);
const visitedKey = 'notRemindChangeHistoryTip';
const { addVisited } = useVisit(visitedKey);
const { getIsVisited } = useVisit(visitedKey);
const props = defineProps<{
caseId: string;
// activeTab: string;
}>();
const columns: MsTableColumn = [
@ -247,20 +248,20 @@
featureCaseStore.getCaseCounts(props.caseId);
}
watch(
() => activeTab.value,
(val) => {
if (val === 'changeHistory') {
doCheckIsTip();
initData();
}
}
);
// watch(
// () => activeTab.value,
// (val) => {
// if (val === 'changeHistory') {
// doCheckIsTip();
// initData();
// }
// }
// );
// onMounted(() => {
// doCheckIsTip();
// initData();
// });
onMounted(() => {
doCheckIsTip();
initData();
});
</script>
<style scoped></style>

View File

@ -1,5 +1,5 @@
<template>
<div class="flex items-center justify-between">
<div class="mb-4 flex items-center justify-between">
<div class="font-medium">{{ t('caseManagement.featureCase.commentList') }}</div>
<div>
<a-radio-group v-model="activeComment" type="button">
@ -11,48 +11,77 @@
</div>
<div>
<!-- 用例评论 -->
<MsComment
v-if="activeComment === 'caseComment'"
:comment-list="commentList"
@delete="handleDelete"
@update-or-add="handleUpdateOrAdd"
/>
<div v-show="activeComment === 'caseComment'">
<MsComment :comment-list="commentList" @delete="handleDelete" @update-or-add="handleUpdateOrAdd" />
<MsEmpty v-if="commentList.length === 0" />
</div>
<!-- 评审评论 -->
<MsComment
v-else-if="activeComment === 'reviewComment'"
:comment-list="reviewCommentList"
@delete="handleDelete"
@update-or-add="handleUpdateOrAdd"
/>
<!-- 执行评论 -->
<!-- <MsComment v-else :comment-list="commentList" @delete="handleDelete" @update-or-add="handleUpdateOrAdd" /> -->
<div v-show="activeComment === 'reviewComment'" 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-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))]" />
{{ t('caseManagement.caseReview.pass') }}
</div>
<div v-else-if="item.status === 'UN_PASS'" class="flex items-center">
<MsIcon type="icon-icon_close_filled" class="mr-[4px] text-[rgb(var(--danger-6))]" />
{{ t('caseManagement.caseReview.fail') }}
</div>
<div v-else-if="item.status === 'UNDER_REVIEWED'" class="flex items-center">
<MsIcon type="icon-icon_warning_filled" class="mr-[4px] text-[rgb(var(--warning-6))]" />
{{ t('caseManagement.caseReview.suggestion') }}
</div>
<div v-else-if="item.status === 'RE_REVIEWED'" class="flex items-center">
<MsIcon type="icon-icon_resubmit_filled" class="mr-[4px] text-[rgb(var(--warning-6))]" />
{{ t('caseManagement.caseReview.reReview') }}
</div>
</div>
</div>
<div class="markdown-body ml-[48px]" v-html="item.contentText"></div>
<div class="ml-[48px] mt-[8px] text-[var(--color-text-4)]">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</div>
</div>
<MsEmpty v-if="reviewCommentList.length === 0" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
import MSAvatar from '@/components/pure/ms-avatar/index.vue';
import MsEmpty from '@/components/pure/ms-empty/index.vue';
import MsComment from '@/components/business/ms-comment';
import { CommentItem, CommentParams } from '@/components/business/ms-comment/types';
import {
addOrUpdateCommentList,
deleteCommentList,
getCommentList,
getReviewCommentList,
updateCommentList,
} from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
const featureCaseStore = useFeatureCaseStore();
const activeTab = computed(() => featureCaseStore.activeTab);
// const activeTab = computed(() => featureCaseStore.activeTab);
const { openModal } = useModal();
const { t } = useI18n();
const props = defineProps<{
caseId: string;
activeTab: string;
}>();
const activeComment = ref('caseComment');
@ -104,13 +133,8 @@
//
async function handleUpdateOrAdd(item: CommentParams, cb: (result: boolean) => void) {
debugger;
try {
if (item.id) {
await updateCommentList(item);
} else {
await updateCommentList(item);
}
await addOrUpdateCommentList(item);
getAllCommentList();
cb(true);
} catch (error) {

View File

@ -65,9 +65,9 @@
</div>
<ms-base-table ref="tableRef" v-bind="propsRes" v-on="propsEvent">
<template #demandName="{ record }">
<a-button type="text" class="flex w-full" @click="openDemandUrl(record.demandUrl)">{{
record.demandName
}}<span>({{ (record.children || []).length || 0 }})</span></a-button>
<a-button type="text" class="flex w-full" @click="openDemandUrl(record.demandUrl)"
>{{ record.demandName }}<span>({{ (record.children || []).length || 0 }})</span></a-button
>
</template>
<template v-for="item in customFields" :key="item.slotName" #[item.dataIndex]="{ record }">
<span> {{ getSlotName(record, item) }} </span>
@ -362,33 +362,33 @@
showAddModel.value = true;
modelForm.value = { ...initModelForm };
}
const activeTab = computed(() => featureCaseStore.activeTab);
// onMounted(async () => {
// try {
// const result = await getCaseRelatedInfo(currentProjectId.value);
// if (result && result.platform_key) {
// platformInfo.value = { ...result };
// }
// } catch (error) {
// console.log(error);
// }
// });
watch(
() => activeTab.value,
async (val) => {
if (val === 'requirement') {
try {
const result = await getCaseRelatedInfo(currentProjectId.value);
if (result && result.platform_key) {
platformInfo.value = { ...result };
}
} catch (error) {
console.log(error);
}
// const activeTab = computed(() => featureCaseStore.activeTab);
onMounted(async () => {
try {
const result = await getCaseRelatedInfo(currentProjectId.value);
if (result && result.platform_key) {
platformInfo.value = { ...result };
}
} catch (error) {
console.log(error);
}
);
});
// watch(
// () => activeTab.value,
// async (val) => {
// if (val === 'requirement') {
// try {
// const result = await getCaseRelatedInfo(currentProjectId.value);
// if (result && result.platform_key) {
// platformInfo.value = { ...result };
// }
// } catch (error) {
// console.log(error);
// }
// }
// }
// );
function getPlatName() {
switch (platformInfo.value.platform_key) {

View File

@ -84,7 +84,7 @@
import { characterLimit } from '@/utils';
const featureCaseStore = useFeatureCaseStore();
const activeTab = computed(() => featureCaseStore.activeTab);
// const activeTab = computed(() => featureCaseStore.activeTab);
const appStore = useAppStore();
@ -95,6 +95,7 @@
const keyword = ref<string>('');
const props = defineProps<{
caseId: string;
activeTab: string;
}>();
const columns: MsTableColumn = [
@ -216,18 +217,18 @@
}
);
watch(
() => activeTab.value,
(val) => {
if (val === 'dependency') {
initData();
}
}
);
// watch(
// () => activeTab.value,
// (val) => {
// if (val === 'dependency') {
// initData();
// }
// }
// );
// onMounted(() => {
// initData();
// });
onMounted(() => {
initData();
});
</script>
<style scoped></style>

View File

@ -28,7 +28,7 @@
:upload-image="handleUploadImage"
class="mt-2"
/>
<div v-else v-dompurify-html="detailForm?.prerequisite || '-'" class="markdown-body"></div>
<div v-else v-dompurify-html="detailForm?.prerequisite || '-'"></div>
</a-form-item>
<a-form-item
field="step"
@ -69,7 +69,6 @@
<div
v-if="detailForm.caseEditType === 'TEXT' && !isEditPreposition"
v-dompurify-html="detailForm.textDescription || '-'"
class="markdown-body"
></div>
</a-form-item>
<a-form-item
@ -83,7 +82,7 @@
v-model:filed-ids="expectedResultFileIds"
:upload-image="handleUploadImage"
/>
<div v-else v-dompurify-html="detailForm.expectedResult || '-'" class="markdown-body"></div>
<div v-else v-dompurify-html="detailForm.expectedResult || '-'"></div>
</a-form-item>
<a-form-item field="description" :label="t('caseManagement.featureCase.remark')">
<MsRichText
@ -92,7 +91,7 @@
v-model:raw="detailForm.description"
:upload-image="handleUploadImage"
/>
<div v-else v-dompurify-html="detailForm.description || '-'" class="markdown-body"></div>
<div v-else v-dompurify-html="detailForm.description || '-'"></div>
</a-form-item>
<div v-if="isEditPreposition" class="flex justify-end">
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
@ -285,7 +284,6 @@
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { downloadByteFile, getGenerateId } from '@/utils';
import { scrollIntoView } from '@/utils/dom';
@ -298,7 +296,7 @@
const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
const featureCaseStore = useFeatureCaseStore();
const { t } = useI18n();
const props = withDefaults(
@ -306,7 +304,7 @@
form: DetailCase;
allowEdit?: boolean; //
formRules?: FormRuleItem[]; //
activeTab?: string | number;
activeTab?: string;
}>(),
{
allowEdit: true, //

View File

@ -32,7 +32,13 @@
@search="loadCaseList"
@press-enter="loadCaseList"
/>
<a-select v-model:model-value="type" :options="typeOptions" class="w-[92px]" @change="loadCaseList" :disabled="onlyMineStatus">
<a-select
v-model:model-value="type"
:options="typeOptions"
class="w-[92px]"
:disabled="onlyMineStatus"
@change="loadCaseList"
>
</a-select>
</div>
<a-spin :loading="caseListLoading" class="h-[calc(100%-46px)] w-full">
@ -210,7 +216,7 @@
</div>
</div>
</div>
<div class="ml-[48px] text-[var(--color-text-2)]" v-html="item.contentText"></div>
<div class="markdown-body ml-[48px]" v-html="item.contentText"></div>
<div class="ml-[48px] mt-[8px] text-[var(--color-text-4)]">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</div>