feat(接口测试): 新增编辑器diff对比功能&接口测试对比布局调整&请求体JSON对比
This commit is contained in:
parent
d90d060e6e
commit
55a33c6a0b
|
@ -93,6 +93,8 @@
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// 编辑器实例,每次调用组件都会创建独立的实例
|
// 编辑器实例,每次调用组件都会创建独立的实例
|
||||||
let editor: monaco.editor.IStandaloneCodeEditor;
|
let editor: monaco.editor.IStandaloneCodeEditor;
|
||||||
|
// 编辑器diffEditor实例 开启diffMode则会初始化
|
||||||
|
let diffEditor: monaco.editor.IStandaloneDiffEditor;
|
||||||
const codeContainerRef = ref();
|
const codeContainerRef = ref();
|
||||||
|
|
||||||
// 用于全屏的容器 ref
|
// 用于全屏的容器 ref
|
||||||
|
@ -266,16 +268,17 @@
|
||||||
codeheight.value = props.height;
|
codeheight.value = props.height;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const editorElement = editor.getDomNode();
|
if (editor) {
|
||||||
|
const editorElement = editor.getDomNode();
|
||||||
if (!editorElement) {
|
if (!editorElement) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取代码编辑器文本行高
|
// 获取代码编辑器文本行高
|
||||||
const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight);
|
const lineHeight = editor?.getOption(monaco.editor.EditorOption.lineHeight);
|
||||||
// 获取代码的行数
|
// 获取代码的行数
|
||||||
const lineCount = editor.getModel()?.getLineCount() || 10;
|
const lineCount = editor?.getModel()?.getLineCount() || 10;
|
||||||
// 计算高度 @desc 原本行数差3行完全展示文本 24为上下的边距为12px
|
// 计算高度 @desc 原本行数差3行完全展示文本 24为上下的边距为12px
|
||||||
const height = (lineCount + 3) * lineHeight;
|
const height = (lineCount + 3) * lineHeight;
|
||||||
codeheight.value = height > 300 ? `${height + 24}px` : '300px';
|
codeheight.value = height > 300 ? `${height + 24}px` : '300px';
|
||||||
|
@ -343,11 +346,50 @@
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 初始化diffEditor
|
||||||
|
const initDiffEditor = (originalValue: string, modifiedValue: string) => {
|
||||||
|
diffEditor = monaco.editor.createDiffEditor(codeContainerRef.value, {
|
||||||
|
automaticLayout: true,
|
||||||
|
padding: {
|
||||||
|
top: 12,
|
||||||
|
bottom: 12,
|
||||||
|
},
|
||||||
|
minimap: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
contextmenu: !props.readOnly,
|
||||||
|
...props,
|
||||||
|
theme: currentTheme.value,
|
||||||
|
lineNumbersMinChars: 3,
|
||||||
|
lineDecorationsWidth: 0,
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const originalModel = monaco.editor.createModel(originalValue, props.language.toLowerCase());
|
||||||
|
const modifiedModel = monaco.editor.createModel(modifiedValue, props.language.toLowerCase());
|
||||||
|
|
||||||
|
diffEditor.setModel({
|
||||||
|
original: originalModel,
|
||||||
|
modified: modifiedModel,
|
||||||
|
});
|
||||||
|
|
||||||
|
handleEditorMount();
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.language,
|
() => props.language,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
currentLanguage.value = newValue;
|
currentLanguage.value = newValue;
|
||||||
monaco.editor.setModelLanguage(editor.getModel()!, newValue.toLowerCase()); // 设置语言,语言 ENUM 是大写的,但是 monaco 需要小写
|
monaco.editor.setModelLanguage(editor.getModel()!, newValue.toLowerCase()); // 设置语言,语言 ENUM 是大写的,但是 monaco 需要小写
|
||||||
|
// 设置对比初始和修改值
|
||||||
|
if (diffEditor) {
|
||||||
|
const originalModel = diffEditor.getModel()?.original;
|
||||||
|
const modifiedModel = diffEditor.getModel()?.modified;
|
||||||
|
if (originalModel && modifiedModel) {
|
||||||
|
monaco.editor.setModelLanguage(originalModel, newValue.toLowerCase());
|
||||||
|
monaco.editor.setModelLanguage(modifiedModel, newValue.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -355,15 +397,28 @@
|
||||||
() => props.readOnly,
|
() => props.readOnly,
|
||||||
(val) => {
|
(val) => {
|
||||||
editor.updateOptions({ readOnly: val });
|
editor.updateOptions({ readOnly: val });
|
||||||
|
if (diffEditor) {
|
||||||
|
diffEditor.updateOptions({ readOnly: val });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
editor.dispose();
|
if (editor) {
|
||||||
|
editor.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diffEditor) {
|
||||||
|
diffEditor.dispose();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
if (props.diffMode) {
|
||||||
|
initDiffEditor(props.originalValue, props.modelValue);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
setEditBoxBg();
|
setEditBoxBg();
|
||||||
if (props.readOnly) {
|
if (props.readOnly) {
|
||||||
format();
|
format();
|
||||||
|
|
|
@ -135,4 +135,14 @@ export const editorProps = {
|
||||||
type: Boolean as PropType<boolean>,
|
type: Boolean as PropType<boolean>,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
// diff对比模式
|
||||||
|
diffMode: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 原来值
|
||||||
|
originalValue: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showDiff(RequestComposition.REST)" class="title">REST</div>
|
<div v-if="showDiff(RequestComposition.REST)" class="title">REST</div>
|
||||||
<div
|
<div
|
||||||
v-if="showDiff(RequestComposition.REST)"
|
v-if="showDiff(RequestComposition.REST) && hiddenEmptyTable(RequestComposition.REST)"
|
||||||
:style="{ 'padding-bottom': `${getBottomDistance(RequestComposition.REST)}px` }"
|
:style="{ 'padding-bottom': `${getBottomDistance(RequestComposition.REST)}px` }"
|
||||||
>
|
>
|
||||||
<MsFormTable
|
<MsFormTable
|
||||||
|
@ -56,20 +56,11 @@
|
||||||
>
|
>
|
||||||
{{ t('case.notSetData') }}
|
{{ t('case.notSetData') }}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 请求体 -->
|
||||||
<div class="title flex items-center justify-between">
|
<div class="title flex items-center justify-between">
|
||||||
<div class="detail-item-title-text">
|
<div class="detail-item-title-text">
|
||||||
{{ `${t('apiTestManagement.requestBody')}-${previewDetail?.body?.bodyType}` }}
|
{{ `${t('apiTestManagement.requestBody')}-${previewDetail?.body?.bodyType}` }}
|
||||||
</div>
|
</div>
|
||||||
<a-radio-group
|
|
||||||
v-if="previewDetail?.body?.bodyType === RequestBodyFormat.JSON && props.isApi"
|
|
||||||
v-model:model-value="bodyShowType"
|
|
||||||
type="button"
|
|
||||||
size="mini"
|
|
||||||
>
|
|
||||||
<a-radio value="schema">Schema</a-radio>
|
|
||||||
<a-radio value="json">JSON</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
|
@ -96,52 +87,13 @@
|
||||||
>
|
>
|
||||||
{{ t('case.notSetData') }}
|
{{ t('case.notSetData') }}
|
||||||
</div>
|
</div>
|
||||||
<template
|
|
||||||
v-else-if="
|
|
||||||
[RequestBodyFormat.JSON, RequestBodyFormat.RAW, RequestBodyFormat.XML].includes(previewDetail?.body?.bodyType)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<MsJsonSchema
|
|
||||||
v-if="previewDetail?.body?.bodyType === RequestBodyFormat.JSON && bodyShowType === 'schema' && props.isApi"
|
|
||||||
:data="previewDetail.body.jsonBody.jsonSchemaTableData"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<MsCodeEditor
|
|
||||||
v-else
|
|
||||||
:model-value="bodyCode"
|
|
||||||
theme="vs"
|
|
||||||
height="200px"
|
|
||||||
:language="bodyCodeLanguage"
|
|
||||||
:show-full-screen="false"
|
|
||||||
:show-theme-change="false"
|
|
||||||
read-only
|
|
||||||
>
|
|
||||||
<template #rightTitle>
|
|
||||||
<a-button
|
|
||||||
type="outline"
|
|
||||||
class="arco-btn-outline--secondary p-[0_8px]"
|
|
||||||
size="mini"
|
|
||||||
@click="copyScript(bodyCode)"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<MsIcon type="icon-icon_copy_outlined" class="text-var(--color-text-4)" size="12" />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
</MsCodeEditor>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useClipboard } from '@vueuse/core';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
|
|
||||||
import { LanguageEnum } from '@/components/pure/ms-code-editor/types';
|
|
||||||
import MsFormTable, { FormTableColumn } from '@/components/pure/ms-form-table/index.vue';
|
import MsFormTable, { FormTableColumn } from '@/components/pure/ms-form-table/index.vue';
|
||||||
import MsJsonSchema from '@/components/pure/ms-json-schema/index.vue';
|
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
@ -150,7 +102,6 @@
|
||||||
|
|
||||||
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
|
|
||||||
const { copy, isSupported } = useClipboard({ legacy: true });
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -259,8 +210,6 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const bodyShowType = ref('schema');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求体
|
* 请求体
|
||||||
*/
|
*/
|
||||||
|
@ -376,42 +325,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const bodyCode = computed(() => {
|
|
||||||
switch (previewDetail.value?.body?.bodyType) {
|
|
||||||
case RequestBodyFormat.FORM_DATA:
|
|
||||||
return previewDetail.value.body.formDataBody?.formValues?.map((item) => `${item.key}:${item.value}`).join('\n');
|
|
||||||
case RequestBodyFormat.WWW_FORM:
|
|
||||||
return previewDetail.value.body.wwwFormBody?.formValues?.map((item) => `${item.key}:${item.value}`).join('\n');
|
|
||||||
case RequestBodyFormat.RAW:
|
|
||||||
return previewDetail.value.body.rawBody?.value;
|
|
||||||
case RequestBodyFormat.JSON:
|
|
||||||
return previewDetail.value.body.jsonBody?.jsonValue;
|
|
||||||
case RequestBodyFormat.XML:
|
|
||||||
return previewDetail.value.body.xmlBody?.value;
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const bodyCodeLanguage = computed(() => {
|
|
||||||
if (previewDetail.value?.body?.bodyType === RequestBodyFormat.JSON) {
|
|
||||||
return LanguageEnum.JSON;
|
|
||||||
}
|
|
||||||
if (previewDetail.value?.body?.bodyType === RequestBodyFormat.XML) {
|
|
||||||
return LanguageEnum.XML;
|
|
||||||
}
|
|
||||||
return LanguageEnum.PLAINTEXT;
|
|
||||||
});
|
|
||||||
|
|
||||||
function copyScript(val: string) {
|
|
||||||
if (isSupported) {
|
|
||||||
copy(val);
|
|
||||||
Message.success(t('common.copySuccess'));
|
|
||||||
} else {
|
|
||||||
Message.warning(t('apiTestDebug.copyNotSupport'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const typeKey = computed(() => (props.isApi ? 'api' : 'case'));
|
const typeKey = computed(() => (props.isApi ? 'api' : 'case'));
|
||||||
|
|
||||||
// 设置非空间距确保行内容长度不同能够水平看齐对比
|
// 设置非空间距确保行内容长度不同能够水平看齐对比
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<template>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
[RequestBodyFormat.JSON, RequestBodyFormat.RAW, RequestBodyFormat.XML].includes(
|
||||||
|
previewDefinedDetail?.body?.bodyType
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<MsCodeEditor
|
||||||
|
v-if="previewDefinedDetail?.body?.bodyType === RequestBodyFormat.JSON"
|
||||||
|
:model-value="bodyCaseCode"
|
||||||
|
theme="vs"
|
||||||
|
height="200px"
|
||||||
|
:language="bodyCodeLanguage"
|
||||||
|
:show-full-screen="false"
|
||||||
|
:show-theme-change="false"
|
||||||
|
read-only
|
||||||
|
is-adaptive
|
||||||
|
diff-mode
|
||||||
|
:original-value="bodyDefinedCode"
|
||||||
|
>
|
||||||
|
<template #rightTitle>
|
||||||
|
<a-button
|
||||||
|
type="outline"
|
||||||
|
class="arco-btn-outline--secondary p-[0_8px]"
|
||||||
|
size="mini"
|
||||||
|
@click="copyScript(bodyDefinedCode)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<MsIcon type="icon-icon_copy_outlined" class="text-var(--color-text-4)" size="12" />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</MsCodeEditor>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useClipboard } from '@vueuse/core';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
|
import { LanguageEnum } from '@/components/pure/ms-code-editor/types';
|
||||||
|
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
import { ExecuteBody } from '@/models/apiTest/common';
|
||||||
|
import { RequestBodyFormat } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
|
|
||||||
|
const MsCodeEditor = defineAsyncComponent(() => import('@/components/pure/ms-code-editor/index.vue'));
|
||||||
|
|
||||||
|
const { copy, isSupported } = useClipboard({ legacy: true });
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
definedDetail: RequestParam;
|
||||||
|
caseDetail: RequestParam;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const previewDefinedDetail = ref<RequestParam>(props.definedDetail);
|
||||||
|
const previewCaseDetail = ref<RequestParam>(props.caseDetail);
|
||||||
|
|
||||||
|
const bodyCodeLanguage = computed(() => {
|
||||||
|
if (previewDefinedDetail.value?.body?.bodyType === RequestBodyFormat.JSON) {
|
||||||
|
return LanguageEnum.JSON;
|
||||||
|
}
|
||||||
|
if (previewDefinedDetail.value?.body?.bodyType === RequestBodyFormat.XML) {
|
||||||
|
return LanguageEnum.XML;
|
||||||
|
}
|
||||||
|
return LanguageEnum.PLAINTEXT;
|
||||||
|
});
|
||||||
|
|
||||||
|
function copyScript(val: string) {
|
||||||
|
if (isSupported) {
|
||||||
|
copy(val);
|
||||||
|
Message.success(t('common.copySuccess'));
|
||||||
|
} else {
|
||||||
|
Message.warning(t('apiTestDebug.copyNotSupport'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBodyCode = (body: ExecuteBody) => {
|
||||||
|
switch (body?.bodyType) {
|
||||||
|
case RequestBodyFormat.FORM_DATA:
|
||||||
|
return body.formDataBody?.formValues?.map((item: any) => `${item.key}:${item.value}`).join('\n');
|
||||||
|
case RequestBodyFormat.WWW_FORM:
|
||||||
|
return body.wwwFormBody?.formValues?.map((item: any) => `${item.key}:${item.value}`).join('\n');
|
||||||
|
case RequestBodyFormat.RAW:
|
||||||
|
return body.rawBody?.value;
|
||||||
|
case RequestBodyFormat.JSON:
|
||||||
|
return body.jsonBody?.jsonValue;
|
||||||
|
case RequestBodyFormat.XML:
|
||||||
|
return body.xmlBody?.value;
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 接口定义Code
|
||||||
|
const bodyDefinedCode = computed(() => getBodyCode(previewDefinedDetail.value?.body));
|
||||||
|
|
||||||
|
// 用例Code
|
||||||
|
const bodyCaseCode = computed(() => getBodyCode(previewCaseDetail.value?.body));
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (props.definedDetail) {
|
||||||
|
previewDefinedDetail.value = cloneDeep(props.definedDetail);
|
||||||
|
}
|
||||||
|
if (props.caseDetail) {
|
||||||
|
previewCaseDetail.value = cloneDeep(props.caseDetail);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -67,14 +67,27 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 对比 -->
|
<!-- 对比 -->
|
||||||
<div class="diff-container">
|
<div class="diff-container">
|
||||||
<div class="diff-item ml-[16px] mr-[8px]">
|
<a-spin class="h-full w-full" :loading="loading">
|
||||||
<div class="title-type"> [{{ apiDetailInfo?.num }}] {{ apiDetailInfo?.name }} </div>
|
<div class="diff-normal">
|
||||||
<DiffItem :diff-distance-map="diffDistanceMap" mode="add" is-api :detail="apiDefinedRequest as RequestParam" />
|
<div class="diff-item">
|
||||||
</div>
|
<div class="title-type"> [{{ apiDetailInfo?.num }}] {{ apiDetailInfo?.name }} </div>
|
||||||
<div class="diff-item ml-[8px] mr-[16px]">
|
<DiffItem
|
||||||
<div class="title-type"> [{{ caseDetail?.num }}] {{ caseDetail?.name }} </div>
|
:diff-distance-map="diffDistanceMap"
|
||||||
<DiffItem :diff-distance-map="diffDistanceMap" mode="delete" :detail="caseDetail as RequestParam" />
|
mode="add"
|
||||||
</div>
|
is-api
|
||||||
|
:detail="apiDefinedRequest as RequestParam"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="diff-item ml-[24px]">
|
||||||
|
<div class="title-type"> [{{ caseDetail?.num }}] {{ caseDetail?.name }} </div>
|
||||||
|
<DiffItem :diff-distance-map="diffDistanceMap" mode="delete" :detail="caseDetail as RequestParam" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DiffRequestBody
|
||||||
|
:defined-detail="apiDefinedRequest as RequestParam"
|
||||||
|
:case-detail="caseDetail as RequestParam"
|
||||||
|
/>
|
||||||
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -86,6 +99,7 @@
|
||||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
import { TabItem } from '@/components/pure/ms-editable-tab/types';
|
import { TabItem } from '@/components/pure/ms-editable-tab/types';
|
||||||
import DiffItem from './diffItem.vue';
|
import DiffItem from './diffItem.vue';
|
||||||
|
import DiffRequestBody from './diffRequestBody.vue';
|
||||||
|
|
||||||
import { getCaseDetail, getDefinitionDetail } from '@/api/modules/api-test/management';
|
import { getCaseDetail, getDefinitionDetail } from '@/api/modules/api-test/management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
@ -323,13 +337,16 @@
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
async function getRequestDetail(definedId: string, apiCaseId: string) {
|
async function getRequestDetail(definedId: string, apiCaseId: string) {
|
||||||
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
await Promise.all([getApiDetail(definedId), getCaseDetailInfo(apiCaseId)]);
|
await Promise.all([getApiDetail(definedId), getCaseDetailInfo(apiCaseId)]);
|
||||||
processData();
|
processData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,31 +378,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.diff-container {
|
.diff-container {
|
||||||
@apply flex;
|
padding: 16px;
|
||||||
.diff-item {
|
min-height: calc(100vh - 110px);
|
||||||
overflow-y: auto;
|
border-radius: 12px;
|
||||||
padding: 16px;
|
background: white;
|
||||||
min-height: calc(100vh - 110px);
|
box-shadow: 0 0 10px rgba(120 56 135/ 5%);
|
||||||
border-radius: 12px;
|
@apply mx-4;
|
||||||
background: white;
|
.diff-normal {
|
||||||
box-shadow: 0 0 10px rgba(120 56 135/ 5%);
|
@apply flex;
|
||||||
@apply flex-1;
|
.diff-item {
|
||||||
.title-type {
|
@apply flex-1;
|
||||||
color: var(--color-text-1);
|
.title-type {
|
||||||
@apply font-medium;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
color: var(--color-text-1);
|
|
||||||
@apply my-4;
|
|
||||||
}
|
|
||||||
.detail-item-title {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
gap: 16px;
|
|
||||||
@apply flex items-center justify-between;
|
|
||||||
.detail-item-title-text {
|
|
||||||
@apply font-medium;
|
|
||||||
|
|
||||||
color: var(--color-text-1);
|
color: var(--color-text-1);
|
||||||
|
@apply font-medium;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
@apply my-4;
|
||||||
|
}
|
||||||
|
.detail-item-title {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
gap: 16px;
|
||||||
|
@apply flex items-center justify-between;
|
||||||
|
.detail-item-title-text {
|
||||||
|
@apply font-medium;
|
||||||
|
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue