fix: 修复接口测试报告bug&公共脚本bug&三方插件bug
This commit is contained in:
parent
1a2b88f7a2
commit
d6cc864783
|
@ -3,6 +3,7 @@ import {
|
||||||
AddCommonScriptUrl,
|
AddCommonScriptUrl,
|
||||||
ConnectionWebsocketUrl,
|
ConnectionWebsocketUrl,
|
||||||
DeleteCommonScriptUrl,
|
DeleteCommonScriptUrl,
|
||||||
|
getChangeHistoryUrl,
|
||||||
GetCommonScriptDetailUrl,
|
GetCommonScriptDetailUrl,
|
||||||
GetCommonScriptPageUrl,
|
GetCommonScriptPageUrl,
|
||||||
GetCommonScriptStatusUrl,
|
GetCommonScriptStatusUrl,
|
||||||
|
@ -19,6 +20,7 @@ import type { ModulesTreeType } from '@/models/caseManagement/featureCase';
|
||||||
import { CommonList, TableQueryParams } from '@/models/common';
|
import { CommonList, TableQueryParams } from '@/models/common';
|
||||||
import type {
|
import type {
|
||||||
AddOrUpdateCommonScript,
|
AddOrUpdateCommonScript,
|
||||||
|
changeHistory,
|
||||||
CommonScriptItem,
|
CommonScriptItem,
|
||||||
TestScriptType,
|
TestScriptType,
|
||||||
} from '@/models/projectManagement/commonScript';
|
} from '@/models/projectManagement/commonScript';
|
||||||
|
@ -57,6 +59,10 @@ export function getCommonScriptStatus(data: AddOrUpdateCommonScript) {
|
||||||
export function getInsertCommonScriptPage(data: TableQueryParams) {
|
export function getInsertCommonScriptPage(data: TableQueryParams) {
|
||||||
return MSR.post<CommonList<CommonScriptItem[]>>({ url: GetInsertCommonScriptPageUrl, data });
|
return MSR.post<CommonList<CommonScriptItem[]>>({ url: GetInsertCommonScriptPageUrl, data });
|
||||||
}
|
}
|
||||||
|
// 获取公共脚本变更历史详情
|
||||||
|
export function getChangeHistory(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<changeHistory[]>>({ url: getChangeHistoryUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格筛选字段的数据查询
|
* 表格筛选字段的数据查询
|
||||||
|
|
|
@ -25,3 +25,5 @@ export const GetFormApiImportModuleCountUrl = '/api/definition/module/count';
|
||||||
export const TestScriptUrl = '/api/test/custom/func/run';
|
export const TestScriptUrl = '/api/test/custom/func/run';
|
||||||
// websoket连接
|
// websoket连接
|
||||||
export const ConnectionWebsocketUrl = '/ws/api';
|
export const ConnectionWebsocketUrl = '/ws/api';
|
||||||
|
// 公共脚本变更历史详情
|
||||||
|
export const getChangeHistoryUrl = '/project/custom/func/history/page';
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full w-full">
|
<conditionContent v-model:data="condition" :disabled="props.disabled" />
|
||||||
<a-scrollbar
|
|
||||||
:style="{
|
|
||||||
overflow: 'auto',
|
|
||||||
height: 'calc(100vh - 490px)',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<conditionContent v-model:data="condition" :disabled="props.disabled" />
|
|
||||||
</a-scrollbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -38,12 +29,6 @@
|
||||||
|
|
||||||
const condition = useVModel(props, 'data', emit);
|
const condition = useVModel(props, 'data', emit);
|
||||||
|
|
||||||
// function handleChange() {
|
|
||||||
// // eslint-disable-next-line no-use-before-define
|
|
||||||
// emit('update:data');
|
|
||||||
// emit('change', { ...condition.value });
|
|
||||||
// }
|
|
||||||
|
|
||||||
const currentEnvConfig = ref({});
|
const currentEnvConfig = ref({});
|
||||||
|
|
||||||
async function initEnvironment() {
|
async function initEnvironment() {
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
:style="{
|
:style="{
|
||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
width: '100%',
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<!-- 响应头 -->
|
<!-- 响应头 -->
|
||||||
|
@ -123,13 +122,13 @@
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
<!-- 脚本 -->
|
<!-- 脚本 -->
|
||||||
<ScriptTab
|
|
||||||
v-if="getCurrentItemState.assertionType === ResponseAssertionType.SCRIPT"
|
|
||||||
v-model:data="getCurrentItemState"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
@change="handleChange"
|
|
||||||
/>
|
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
|
<ScriptTab
|
||||||
|
v-if="getCurrentItemState.assertionType === ResponseAssertionType.SCRIPT"
|
||||||
|
v-model:data="getCurrentItemState"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -383,7 +383,7 @@
|
||||||
treeRef.value?.checkAll(val);
|
treeRef.value?.checkAll(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function expandNode(key: string | number, expanded: boolean) {
|
function expandNode(key: (string | number)[] | (string | number), expanded: boolean) {
|
||||||
treeRef.value?.expandNode(key, expanded);
|
treeRef.value?.expandNode(key, expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ export const INT = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MULTIPLE_INPUT = {
|
export const MULTIPLE_INPUT = {
|
||||||
type: 'a-input-tag',
|
type: 'MsTagsInput',
|
||||||
field: 'fieldName',
|
field: 'fieldName',
|
||||||
title: '',
|
title: '',
|
||||||
value: [],
|
value: [],
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
import { ref, watch, watchEffect } from 'vue';
|
import { ref, watch, watchEffect } from 'vue';
|
||||||
|
|
||||||
|
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||||
import JiraKey from './comp/jiraKey.vue';
|
import JiraKey from './comp/jiraKey.vue';
|
||||||
import PassWord from './formcreate-password.vue';
|
import PassWord from './formcreate-password.vue';
|
||||||
import SearchSelect from './searchSelect.vue';
|
import SearchSelect from './searchSelect.vue';
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
formCreate.component('PassWord', PassWord);
|
formCreate.component('PassWord', PassWord);
|
||||||
formCreate.component('SearchSelect', SearchSelect);
|
formCreate.component('SearchSelect', SearchSelect);
|
||||||
formCreate.component('JiraKey', JiraKey);
|
formCreate.component('JiraKey', JiraKey);
|
||||||
|
formCreate.component('MsTagsInput', MsTagsInput);
|
||||||
const FormCreate = formCreate.$form();
|
const FormCreate = formCreate.$form();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
import { FieldTypeFormRules } from '@/components/pure/ms-form-create/form-create';
|
import { FieldTypeFormRules } from '@/components/pure/ms-form-create/form-create';
|
||||||
|
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||||
import JiraKey from './comp/jiraKey.vue';
|
import JiraKey from './comp/jiraKey.vue';
|
||||||
import PassWord from './formcreate-password.vue';
|
import PassWord from './formcreate-password.vue';
|
||||||
import SearchSelect from './searchSelect.vue';
|
import SearchSelect from './searchSelect.vue';
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
formCreate.component('PassWord', PassWord);
|
formCreate.component('PassWord', PassWord);
|
||||||
formCreate.component('SearchSelect', SearchSelect);
|
formCreate.component('SearchSelect', SearchSelect);
|
||||||
formCreate.component('JiraKey', JiraKey);
|
formCreate.component('JiraKey', JiraKey);
|
||||||
|
formCreate.component('MsTagsInput', MsTagsInput);
|
||||||
|
|
||||||
const FormCreate = formCreate.$form();
|
const FormCreate = formCreate.$form();
|
||||||
// 处理配置项
|
// 处理配置项
|
||||||
|
|
|
@ -1,37 +1,39 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="`flex w-full items-center ${props.class}`">
|
<div class="w-full">
|
||||||
<a-input-tag
|
<div :class="`flex w-full items-center ${props.class}`">
|
||||||
v-model:model-value="innerModelValue"
|
<a-input-tag
|
||||||
v-model:input-value="innerInputValue"
|
v-model:model-value="innerModelValue"
|
||||||
:error="isError"
|
v-model:input-value="innerInputValue"
|
||||||
:placeholder="t(props.placeholder || 'ms.tagsInput.tagsInputPlaceholder')"
|
:error="isError"
|
||||||
:allow-clear="props.allowClear"
|
:placeholder="t(props.placeholder || 'ms.tagsInput.tagsInputPlaceholder')"
|
||||||
:retain-input-value="props.retainInputValue"
|
:allow-clear="props.allowClear"
|
||||||
:unique-value="props.uniqueValue"
|
:retain-input-value="props.retainInputValue"
|
||||||
:max-tag-count="props.maxTagCount"
|
:unique-value="props.uniqueValue"
|
||||||
:readonly="props.readonly"
|
:max-tag-count="props.maxTagCount"
|
||||||
:class="props.inputClass"
|
:readonly="props.readonly"
|
||||||
:size="props.size"
|
:class="props.inputClass"
|
||||||
:disabled="props.disabled"
|
:size="props.size"
|
||||||
@press-enter="tagInputEnter"
|
:disabled="props.disabled"
|
||||||
@blur="tagInputBlur"
|
@press-enter="tagInputEnter"
|
||||||
@clear="emit('clear')"
|
@blur="tagInputBlur"
|
||||||
@click="emit('click')"
|
@clear="emit('clear')"
|
||||||
>
|
@click="emit('click')"
|
||||||
<template v-if="$slots.prefix" #prefix>
|
>
|
||||||
<slot name="prefix"></slot>
|
<template v-if="$slots.prefix" #prefix>
|
||||||
</template>
|
<slot name="prefix"></slot>
|
||||||
<template v-if="$slots.tag" #tag="{ data }">
|
</template>
|
||||||
<slot name="tag" :data="data"></slot>
|
<template v-if="$slots.tag" #tag="{ data }">
|
||||||
</template>
|
<slot name="tag" :data="data"></slot>
|
||||||
<template v-if="$slots.suffix" #suffix>
|
</template>
|
||||||
<slot name="suffix"></slot>
|
<template v-if="$slots.suffix" #suffix>
|
||||||
</template>
|
<slot name="suffix"></slot>
|
||||||
</a-input-tag>
|
</template>
|
||||||
|
</a-input-tag>
|
||||||
|
</div>
|
||||||
|
<div v-if="isError" class="ml-[1px] flex justify-start text-[12px] text-[rgb(var(--danger-6))]">
|
||||||
|
{{ t('common.tagInputMaxLength', { number: props.maxLength }) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="isError" class="ml-[1px] text-[12px] text-[rgb(var(--danger-6))]">
|
|
||||||
{{ t('common.tagInputMaxLength', { number: props.maxLength }) }}
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
|
@ -105,6 +105,7 @@ export interface ScenarioItemType {
|
||||||
children: ScenarioItemType[];
|
children: ScenarioItemType[];
|
||||||
level?: number;
|
level?: number;
|
||||||
stepDetail: ReportStepDetailItem;
|
stepDetail: ReportStepDetailItem;
|
||||||
|
stepChildren?: ScenarioItemType[]; // 步骤子步骤
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ScenarioDetailItem = Partial<ScenarioItemType>;
|
export type ScenarioDetailItem = Partial<ScenarioItemType>;
|
||||||
|
|
|
@ -66,3 +66,16 @@ export interface TestScriptType {
|
||||||
script: string;
|
script: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
}
|
}
|
||||||
|
// 变更历史详情
|
||||||
|
export interface changeHistory {
|
||||||
|
id: string;
|
||||||
|
projectId: string;
|
||||||
|
createTime: string;
|
||||||
|
createUser: string;
|
||||||
|
sourceId: string;
|
||||||
|
type: string;
|
||||||
|
module: string;
|
||||||
|
refId: string;
|
||||||
|
createUserName: string;
|
||||||
|
versionName: string;
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<slot name="titleRight"></slot>
|
<slot name="titleRight"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="data.length > 0 && activeItem" class="flex h-[calc(100%-40px)] gap-[8px]">
|
<div v-if="data.length > 0 && activeItem" class="flex h-[calc(100%-40px)] w-full gap-[8px]">
|
||||||
<div class="h-full w-[20%] min-w-[220px]">
|
<div class="h-full w-[20%] min-w-[220px]">
|
||||||
<conditionList
|
<conditionList
|
||||||
v-model:list="data"
|
v-model:list="data"
|
||||||
|
|
|
@ -310,14 +310,16 @@
|
||||||
|
|
||||||
const isShowLoopControl = computed(() => {
|
const isShowLoopControl = computed(() => {
|
||||||
return (
|
return (
|
||||||
props.stepItem?.children && props.stepItem.children.length && showApiType.value.includes(props.stepItem.stepType)
|
props.stepItem?.stepChildren &&
|
||||||
|
props.stepItem?.stepChildren.length &&
|
||||||
|
showApiType.value.includes(props.stepItem.stepType)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const controlCurrent = ref<number>(1);
|
const controlCurrent = ref<number>(1);
|
||||||
const controlTotal = computed(() => {
|
const controlTotal = computed(() => {
|
||||||
if (props.stepItem?.children) {
|
if (props.stepItem?.stepChildren) {
|
||||||
return props.stepItem.children.length || 0;
|
return props.stepItem?.stepChildren.length || 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
@ -326,8 +328,8 @@
|
||||||
* 循环次数控制器
|
* 循环次数控制器
|
||||||
*/
|
*/
|
||||||
function loadControlLoop() {
|
function loadControlLoop() {
|
||||||
if (isShowLoopControl.value) {
|
if (isShowLoopControl.value && props.stepItem?.stepChildren) {
|
||||||
const loopStepId = props.stepItem?.children[controlCurrent.value - 1].stepId;
|
const loopStepId = props.stepItem?.stepChildren[controlCurrent.value - 1].stepId;
|
||||||
if (loopStepId) {
|
if (loopStepId) {
|
||||||
getStepDetail(loopStepId);
|
getStepDetail(loopStepId);
|
||||||
}
|
}
|
||||||
|
@ -340,8 +342,8 @@
|
||||||
() => props.stepItem?.stepId,
|
() => props.stepItem?.stepId,
|
||||||
(val) => {
|
(val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
if (isShowLoopControl.value) {
|
if (isShowLoopControl.value && props.stepItem?.stepChildren) {
|
||||||
getStepDetail(props.stepItem?.children[controlCurrent.value - 1].stepId as string);
|
getStepDetail(props.stepItem?.stepChildren[controlCurrent.value - 1].stepId as string);
|
||||||
} else {
|
} else {
|
||||||
getStepDetail(val);
|
getStepDetail(val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
required: true,
|
required: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const reportStepDetail = ref<ReportDetail>({
|
const initReportStepDetail = {
|
||||||
id: '',
|
id: '',
|
||||||
name: '', // 报告名称
|
name: '', // 报告名称
|
||||||
testPlanId: '',
|
testPlanId: '',
|
||||||
|
@ -96,6 +96,9 @@
|
||||||
children: [], // 步骤列表
|
children: [], // 步骤列表
|
||||||
stepTotal: 0, // 步骤总数
|
stepTotal: 0, // 步骤总数
|
||||||
console: '',
|
console: '',
|
||||||
|
};
|
||||||
|
const reportStepDetail = ref<ReportDetail>({
|
||||||
|
...initReportStepDetail,
|
||||||
});
|
});
|
||||||
async function getReportCaseDetail() {
|
async function getReportCaseDetail() {
|
||||||
try {
|
try {
|
||||||
|
@ -110,6 +113,7 @@
|
||||||
() => innerVisible.value,
|
() => innerVisible.value,
|
||||||
async (val) => {
|
async (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
reportStepDetail.value = { ...initReportStepDetail };
|
||||||
await getReportCaseDetail();
|
await getReportCaseDetail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,39 @@
|
||||||
<div class="relative mr-4">
|
<div class="relative mr-4">
|
||||||
<div class="charts absolute text-center">
|
<div class="charts absolute text-center">
|
||||||
<div class="text-[12px] text-[(var(--color-text-4))]">{{ t('report.detail.api.total') }}</div>
|
<div class="text-[12px] text-[(var(--color-text-4))]">{{ t('report.detail.api.total') }}</div>
|
||||||
<div class="text-[18px] font-medium">{{ props.requestTotal }}</div>
|
<a-popover position="bottom" content-class="response-popover-content">
|
||||||
|
<div class="flex justify-center text-[18px] font-medium">
|
||||||
|
<div class="one-line-text max-w-[60px]">{{ getIndicators(requestTotal) }}</div>
|
||||||
|
</div>
|
||||||
|
<template #content>
|
||||||
|
<div class="min-w-[176px] max-w-[400px] p-4 text-[14px]">
|
||||||
|
<div class="text-[12px] font-medium text-[var(--color-text-4)]">{{ t('report.detail.api.total') }}</div>
|
||||||
|
<div class="mt-2 text-[18px] font-medium text-[var(--color-text-1)]">{{
|
||||||
|
getIndicators(addCommasToNumber(requestTotal))
|
||||||
|
}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-popover>
|
||||||
</div>
|
</div>
|
||||||
<MsChart width="110px" height="110px" :options="props.options" />
|
<a-popover position="bottom" content-class="response-popover-content">
|
||||||
|
<div> <MsChart width="110px" height="110px" :options="props.options" /></div>
|
||||||
|
<template #content>
|
||||||
|
<div class="min-w-[176px] max-w-[400px] p-4">
|
||||||
|
<div v-for="item of legendData" :key="item.value" class="mb-2 flex justify-between">
|
||||||
|
<div class="chart-flag flex items-center">
|
||||||
|
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full" :class="item.class"></div>
|
||||||
|
<div class="mr-2 text-[var(--color-text-4)]">{{ item.label }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="count font-medium">{{ item.count || 0 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chart-legend grid flex-1 gap-y-3">
|
<div class="chart-legend grid flex-1 gap-y-3">
|
||||||
<!-- 图例开始 -->
|
<!-- 图例开始 -->
|
||||||
<div v-for="item of props.legendData" :key="item.value" class="chart-legend-item">
|
<div v-for="item of legendData" :key="item.value" class="chart-legend-item">
|
||||||
<div class="chart-flag">
|
<div class="chart-flag">
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full" :class="item.class"></div>
|
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full" :class="item.class"></div>
|
||||||
<div class="mr-2 text-[var(--color-text-4)]">{{ item.label }}</div>
|
<div class="mr-2 text-[var(--color-text-4)]">{{ item.label }}</div>
|
||||||
|
@ -30,9 +56,12 @@
|
||||||
import MsChart from '@/components/pure/chart/index.vue';
|
import MsChart from '@/components/pure/chart/index.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { addCommasToNumber, formatDuration } from '@/utils';
|
||||||
|
|
||||||
import type { LegendData } from '@/models/apiTest/report';
|
import type { LegendData } from '@/models/apiTest/report';
|
||||||
|
|
||||||
|
import { getIndicators } from '../../utils';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
options: Record<string, any>;
|
options: Record<string, any>;
|
||||||
|
@ -58,6 +87,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -228,6 +228,7 @@
|
||||||
const charOptions = ref({
|
const charOptions = ref({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
|
show: false,
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|
|
@ -195,10 +195,6 @@
|
||||||
reportStepDetail.value = cloneDeep(detail);
|
reportStepDetail.value = cloneDeep(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
detailDrawerRef.value?.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => showDrawer.value,
|
() => showDrawer.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -203,10 +203,6 @@
|
||||||
|
|
||||||
const detailDrawerRef = ref();
|
const detailDrawerRef = ref();
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
detailDrawerRef.value?.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => showDrawer.value,
|
() => showDrawer.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -47,8 +47,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a-popover position="bottom" content-class="response-popover-content">
|
<a-popover position="bottom" content-class="response-popover-content">
|
||||||
<span class="ml-4 text-[18px] font-medium">{{ getTotalTime.split('-')[0] || '-' }}</span>
|
<div class="flex items-center">
|
||||||
<span class="ml-1 text-[var(--color-text-4)]">{{ getTotalTime.split('-')[1] || 'ms' }}</span>
|
<div class="one-line-text ml-4 max-w-[80px] text-[18px] font-medium">{{
|
||||||
|
getTotalTime.split('-')[0] || '-'
|
||||||
|
}}</div>
|
||||||
|
<div class="ml-1 text-[var(--color-text-4)]">{{ getTotalTime.split('-')[1] || 'ms' }}</div>
|
||||||
|
</div>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
||||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.totalTime') }}</div>
|
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.totalTime') }}</div>
|
||||||
|
@ -68,7 +72,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a-popover position="bottom" content-class="response-popover-content">
|
<a-popover position="bottom" content-class="response-popover-content">
|
||||||
<span class="ml-4 text-[18px] font-medium">{{
|
<span class="one-line-text ml-4 inline-block max-w-[80px] align-middle text-[18px] font-medium">{{
|
||||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '-'
|
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '-'
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
||||||
|
@ -147,26 +151,11 @@
|
||||||
|
|
||||||
<div class="request-analyze">
|
<div class="request-analyze">
|
||||||
<div class="block-title">{{ t('report.detail.api.requestAnalysis') }}</div>
|
<div class="block-title">{{ t('report.detail.api.requestAnalysis') }}</div>
|
||||||
<div class="flex min-h-[110px] items-center">
|
<SetReportChart
|
||||||
<div class="relative mr-4">
|
:legend-data="legendData"
|
||||||
<div class="charts absolute text-center">
|
:options="charOptions"
|
||||||
<div class="text-[12px] text-[(var(--color-text-4))]">{{ t('report.detail.api.total') }}</div>
|
:request-total="getIndicators(detail.requestTotal)"
|
||||||
<div class="text-[18px] font-medium">{{ getIndicators(detail.requestTotal) }}</div>
|
/>
|
||||||
</div>
|
|
||||||
<MsChart width="110px" height="110px" :options="charOptions" />
|
|
||||||
</div>
|
|
||||||
<div class="chart-legend grid flex-1 gap-y-3">
|
|
||||||
<!-- 图例开始 -->
|
|
||||||
<div v-for="item of legendData" :key="item.value" class="chart-legend-item">
|
|
||||||
<div class="chart-flag">
|
|
||||||
<div class="mb-[2px] mr-[4px] h-[6px] w-[6px] rounded-full" :class="item.class"></div>
|
|
||||||
<div class="mr-2 text-[var(--color-text-4)]">{{ item.label }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="count">{{ item.count || 0 }}</div>
|
|
||||||
<div class="count">{{ item.rote || 0 }}%</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 报告步骤分析和请求分析结束 -->
|
<!-- 报告步骤分析和请求分析结束 -->
|
||||||
|
@ -182,10 +171,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
|
||||||
import MsChart from '@/components/pure/chart/index.vue';
|
import MsChart from '@/components/pure/chart/index.vue';
|
||||||
import MsColorLine from '@/components/pure/ms-color-line/index.vue';
|
import SetReportChart from './case/setReportChart.vue';
|
||||||
import ReportDetailHeader from './reportDetailHeader.vue';
|
import ReportDetailHeader from './reportDetailHeader.vue';
|
||||||
import reportInfoHeader from './step/reportInfoHeaders.vue';
|
import reportInfoHeader from './step/reportInfoHeaders.vue';
|
||||||
import StepProgress from './stepProgress.vue';
|
import StepProgress from './stepProgress.vue';
|
||||||
|
@ -265,6 +253,7 @@
|
||||||
const legendData = ref<LegendData[]>([]);
|
const legendData = ref<LegendData[]>([]);
|
||||||
const charOptions = ref({
|
const charOptions = ref({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
show: false,
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -449,6 +438,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
isStaticItemHeight: true,
|
isStaticItemHeight: true,
|
||||||
estimatedSize: 48,
|
estimatedSize: 48,
|
||||||
}"
|
}"
|
||||||
|
:animation="false"
|
||||||
action-on-node-click="expand"
|
action-on-node-click="expand"
|
||||||
disabled-title-tooltip
|
disabled-title-tooltip
|
||||||
block-node
|
block-node
|
||||||
|
@ -26,7 +27,8 @@
|
||||||
@more-actions-close="() => setFocusNodeKey('')"
|
@more-actions-close="() => setFocusNodeKey('')"
|
||||||
>
|
>
|
||||||
<template #title="step">
|
<template #title="step">
|
||||||
<div class="flex flex-col">
|
<!-- <div class="absolute h-full w-full top-0" style="border: 1px solid #0cc"></div> -->
|
||||||
|
<div class="flex flex-col" @click="handleStop($event, step)">
|
||||||
<div class="flex w-full items-center gap-[8px]">
|
<div class="flex w-full items-center gap-[8px]">
|
||||||
<div
|
<div
|
||||||
class="flex h-[16px] min-w-[16px] items-center justify-center rounded-full bg-[var(--color-text-brand)] px-[2px] !text-white"
|
class="flex h-[16px] min-w-[16px] items-center justify-center rounded-full bg-[var(--color-text-brand)] px-[2px] !text-white"
|
||||||
|
@ -44,7 +46,10 @@
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="flex cursor-pointer items-center gap-[2px] text-[var(--color-text-4)]">
|
<div
|
||||||
|
v-if="!(step.children && step.children.length && showApiType.includes(step.stepType))"
|
||||||
|
class="flex cursor-pointer items-center gap-[2px] text-[var(--color-text-4)]"
|
||||||
|
>
|
||||||
<MsIcon
|
<MsIcon
|
||||||
:type="step.expanded ? 'icon-icon_split_turn-down_arrow' : 'icon-icon_split-turn-down-left'"
|
:type="step.expanded ? 'icon-icon_split_turn-down_arrow' : 'icon-icon_split-turn-down-left'"
|
||||||
:size="14"
|
:size="14"
|
||||||
|
@ -66,8 +71,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-tooltip :content="step.name" position="tl">
|
<a-tooltip :content="step.name" position="tl">
|
||||||
<div class="step-name-container w-full flex-grow" @click.stop="showDetail(step)">
|
<div
|
||||||
<div class="one-line-text mx-[4px] max-w-[150px] text-[var(--color-text-1)]">
|
class="step-name-container"
|
||||||
|
:class="{
|
||||||
|
'w-full flex-grow': showApiType.includes(step.stepType),
|
||||||
|
}"
|
||||||
|
@click="showDetail($event, step)"
|
||||||
|
>
|
||||||
|
<div class="one-line-text mx-[4px] max-w-[300px] text-[var(--color-text-1)]">
|
||||||
{{ step.name }}
|
{{ step.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,6 +197,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
import { MsTreeExpandedData } from '@/components/business/ms-tree/types';
|
import { MsTreeExpandedData } from '@/components/business/ms-tree/types';
|
||||||
|
|
||||||
|
@ -226,14 +238,19 @@
|
||||||
const innerExpandedKeys = defineModel<(string | number)[]>('expandedKeys', {
|
const innerExpandedKeys = defineModel<(string | number)[]>('expandedKeys', {
|
||||||
required: false,
|
required: false,
|
||||||
});
|
});
|
||||||
|
const showApiType = ref<string[]>([ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST]);
|
||||||
|
|
||||||
|
const innerNumber = ref<number>(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理步骤展开折叠
|
* 处理步骤展开折叠
|
||||||
*/
|
*/
|
||||||
function handleStepExpand(data: MsTreeExpandedData) {
|
function handleStepExpand(data: MsTreeExpandedData) {
|
||||||
const realStep = findNodeByKey<ScenarioItemType>(steps.value, data.node?.stepId, 'stepId');
|
const isNotAllowExpand =
|
||||||
if (realStep) {
|
data.node?.children && data.node?.children.length && showApiType.value.includes(data.node?.stepType);
|
||||||
realStep.expanded = !realStep.expanded;
|
if (isNotAllowExpand && data.node && data.node.children) {
|
||||||
|
data.node.stepChildren = cloneDeep(data.node.children);
|
||||||
|
data.node.children = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,12 +272,17 @@
|
||||||
|
|
||||||
function expandHandler(item: ScenarioItemType) {
|
function expandHandler(item: ScenarioItemType) {
|
||||||
const realStep = findNodeByKey<ScenarioItemType>(steps.value, item.stepId, 'stepId');
|
const realStep = findNodeByKey<ScenarioItemType>(steps.value, item.stepId, 'stepId');
|
||||||
// TODO
|
|
||||||
if (realStep) {
|
if (realStep) {
|
||||||
|
const isNotAllowExpand =
|
||||||
|
realStep.children && realStep?.children.length && showApiType.value.includes(realStep?.stepType);
|
||||||
|
if (isNotAllowExpand) {
|
||||||
|
realStep.stepChildren = cloneDeep(realStep.children);
|
||||||
|
realStep.children = [];
|
||||||
|
}
|
||||||
realStep.fold = !realStep.fold;
|
realStep.fold = !realStep.fold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const showApiType = ref<string[]>([ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST]);
|
|
||||||
const showCondition = ref<string[]>([
|
const showCondition = ref<string[]>([
|
||||||
ScenarioStepType.API,
|
ScenarioStepType.API,
|
||||||
ScenarioStepType.API_CASE,
|
ScenarioStepType.API_CASE,
|
||||||
|
@ -276,7 +298,7 @@
|
||||||
return props.activeType === 'tab';
|
return props.activeType === 'tab';
|
||||||
}
|
}
|
||||||
const activeItem = ref();
|
const activeItem = ref();
|
||||||
function showDetail(item: ScenarioItemType) {
|
function showDetail(event: Event, item: ScenarioItemType) {
|
||||||
if (props.activeType === 'tab') {
|
if (props.activeType === 'tab') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -285,6 +307,7 @@
|
||||||
}
|
}
|
||||||
activeItem.value = item;
|
activeItem.value = item;
|
||||||
emit('detail', activeItem.value);
|
emit('detail', activeItem.value);
|
||||||
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 响应状态码对应颜色
|
// 响应状态码对应颜色
|
||||||
|
@ -315,6 +338,12 @@
|
||||||
}
|
}
|
||||||
return item.children && item.children.length > 0;
|
return item.children && item.children.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleStop(event: Event, step: ScenarioItemType) {
|
||||||
|
if (step.children && step.children.length && showApiType.value.includes(step.stepType)) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
<template>
|
<template>
|
||||||
<MsDrawer
|
<MsDrawer v-model:visible="scriptDetailDrawer" :title="form.name" :width="800" :footer="false" unmount-on-close>
|
||||||
v-model:visible="scriptDetailDrawer"
|
|
||||||
:title="t('project.commonScript.publicScriptName')"
|
|
||||||
:width="768"
|
|
||||||
:footer="false"
|
|
||||||
unmount-on-close
|
|
||||||
>
|
|
||||||
<template #headerLeft>
|
<template #headerLeft>
|
||||||
<MsTag class="ml-1" type="success" theme="light">{{ t('project.commonScript.testSuccess') }}</MsTag>
|
<MsTag class="ml-1" type="success" theme="light">{{ t('project.commonScript.testSuccess') }}</MsTag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #tbutton>
|
||||||
|
<div class="flex">
|
||||||
|
<MsButton
|
||||||
|
v-permission="['PROJECT_API_REPORT:READ+SHARE']"
|
||||||
|
type="icon"
|
||||||
|
status="secondary"
|
||||||
|
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||||
|
@click="editHandler"
|
||||||
|
>
|
||||||
|
<MsIcon type="icon-icon_edit_outlined" class="mr-2 font-[16px]" />
|
||||||
|
{{ t('common.edit') }}
|
||||||
|
</MsButton>
|
||||||
|
<MsButton
|
||||||
|
v-permission="['PROJECT_API_REPORT:READ+SHARE']"
|
||||||
|
type="icon"
|
||||||
|
status="secondary"
|
||||||
|
:loading="loading"
|
||||||
|
class="mr-4 !rounded-[var(--border-radius-small)]"
|
||||||
|
@click="testHandler"
|
||||||
|
>
|
||||||
|
{{ t('apiTestDebug.test') }}
|
||||||
|
</MsButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<a-radio-group v-model="showType" type="button" size="small">
|
<a-radio-group v-model="showType" type="button" size="small">
|
||||||
<a-radio value="detail">{{ t('project.commonScript.detail') }}</a-radio>
|
<a-radio value="detail">{{ t('project.commonScript.detail') }}</a-radio>
|
||||||
<a-radio value="changeHistory">{{ t('project.commonScript.changeHistory') }}</a-radio>
|
<a-radio value="changeHistory">{{ t('project.commonScript.changeHistory') }}</a-radio>
|
||||||
|
@ -27,11 +45,11 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span>{{ t('project.commonScript.inputParams') }}</span>
|
<div class="mb-4">{{ t('project.commonScript.inputParams') }}</div>
|
||||||
|
|
||||||
<ms-base-table v-bind="propsRes" ref="tableRef" class="mb-4" no-disable v-on="propsEvent">
|
<ms-base-table v-bind="propsRes" ref="tableRef" class="mb-4" no-disable v-on="propsEvent">
|
||||||
<template #mustContain="{ record }">
|
<template #mustContain="{ record }">
|
||||||
<a-checkbox v-model:model-value="record.mustContain" :disabled="true"></a-checkbox>
|
<a-checkbox v-model:model-value="record.required" :disabled="true"></a-checkbox>
|
||||||
</template>
|
</template>
|
||||||
</ms-base-table>
|
</ms-base-table>
|
||||||
|
|
||||||
|
@ -46,7 +64,7 @@
|
||||||
width="100%"
|
width="100%"
|
||||||
height="calc(100vh - 155px)"
|
height="calc(100vh - 155px)"
|
||||||
theme="MS-text"
|
theme="MS-text"
|
||||||
:read-only="false"
|
:read-only="true"
|
||||||
:show-full-screen="false"
|
:show-full-screen="false"
|
||||||
:show-theme-change="false"
|
:show-theme-change="false"
|
||||||
/>
|
/>
|
||||||
|
@ -55,12 +73,15 @@
|
||||||
v-else
|
v-else
|
||||||
v-bind="changeHistoryPropsRes"
|
v-bind="changeHistoryPropsRes"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
class="mb-4"
|
class="mt-4"
|
||||||
no-disable
|
no-disable
|
||||||
v-on="changeHistoryPropsEvent"
|
v-on="changeHistoryPropsEvent"
|
||||||
>
|
>
|
||||||
<template #changeSerialNumber="{ record }"
|
<template #id="{ record }">
|
||||||
><div class="flex items-center"> {{ record.changeSerialNumber }} <MsTag>当前</MsTag> </div>
|
<div class="flex items-center">
|
||||||
|
<div class="one-line-text mr-2 max-w-[200px]"> {{ record.id }} </div>
|
||||||
|
<MsTag>{{ t('project.processor.current') }}</MsTag>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #operation="{ record }">
|
<template #operation="{ record }">
|
||||||
<MsButton status="primary" @click="recoverHandler(record)">
|
<MsButton status="primary" @click="recoverHandler(record)">
|
||||||
|
@ -84,12 +105,21 @@
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||||
|
|
||||||
import { getCommonScriptDetail } from '@/api/modules/project-management/commonScript';
|
import {
|
||||||
|
getChangeHistory,
|
||||||
|
getCommonScriptDetail,
|
||||||
|
getSocket,
|
||||||
|
testCommonScript,
|
||||||
|
} from '@/api/modules/project-management/commonScript';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import useAppStore from '@/store/modules/app';
|
||||||
|
import { getGenerateId } from '@/utils';
|
||||||
|
|
||||||
import type { AddOrUpdateCommonScript } from '@/models/projectManagement/commonScript';
|
import type { AddOrUpdateCommonScript } from '@/models/projectManagement/commonScript';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -97,7 +127,7 @@
|
||||||
scriptId: string; // 脚本id
|
scriptId: string; // 脚本id
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits(['update:visible', 'change']);
|
const emit = defineEmits(['update:visible', 'change', 'update']);
|
||||||
|
|
||||||
const showType = ref('detail');
|
const showType = ref('detail');
|
||||||
|
|
||||||
|
@ -113,8 +143,8 @@
|
||||||
const columns: MsTableColumn = [
|
const columns: MsTableColumn = [
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.ParameterNames',
|
title: 'project.commonScript.ParameterNames',
|
||||||
slotName: 'name',
|
slotName: 'key',
|
||||||
dataIndex: 'name',
|
dataIndex: 'key',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
},
|
},
|
||||||
|
@ -127,8 +157,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.description',
|
title: 'project.commonScript.description',
|
||||||
slotName: 'desc',
|
slotName: 'description',
|
||||||
dataIndex: 'desc',
|
dataIndex: 'description',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -139,7 +169,7 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const { propsRes, propsEvent, setProps } = useTable(undefined, {
|
const { propsRes, propsEvent } = useTable(undefined, {
|
||||||
columns,
|
columns,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
showSetting: false,
|
showSetting: false,
|
||||||
|
@ -149,70 +179,61 @@
|
||||||
|
|
||||||
const scriptType = ref<'commonScript' | 'executionResult'>('commonScript');
|
const scriptType = ref<'commonScript' | 'executionResult'>('commonScript');
|
||||||
|
|
||||||
const detailValue = ref('');
|
|
||||||
|
|
||||||
const changeHistoryColumns: MsTableColumn = [
|
const changeHistoryColumns: MsTableColumn = [
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.changeSerialNumber',
|
title: 'project.commonScript.changeSerialNumber',
|
||||||
slotName: 'changeSerialNumber',
|
slotName: 'id',
|
||||||
dataIndex: 'changeSerialNumber',
|
dataIndex: 'id',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
|
width: 300,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.actionType',
|
title: 'project.commonScript.actionType',
|
||||||
slotName: 'actionType',
|
slotName: 'type',
|
||||||
dataIndex: 'actionType',
|
dataIndex: 'type',
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
|
width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.actionUser',
|
title: 'project.commonScript.actionUser',
|
||||||
dataIndex: 'actionUser',
|
dataIndex: 'createUserName',
|
||||||
slotName: 'actionUser',
|
slotName: 'createUserName',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'project.commonScript.updateTime',
|
title: 'project.commonScript.updateTime',
|
||||||
dataIndex: 'updateTime',
|
dataIndex: 'createTime',
|
||||||
slotName: 'updateTime',
|
slotName: 'createTime',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
// TODO:这个版本不上恢复
|
||||||
title: 'project.commonScript.tableColumnActions',
|
// {
|
||||||
slotName: 'operation',
|
// title: 'project.commonScript.tableColumnActions',
|
||||||
dataIndex: 'operation',
|
// slotName: 'operation',
|
||||||
fixed: 'right',
|
// dataIndex: 'operation',
|
||||||
width: 140,
|
// fixed: 'right',
|
||||||
showInTable: true,
|
// width: 140,
|
||||||
showDrag: false,
|
// showInTable: true,
|
||||||
},
|
// showDrag: false,
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
const {
|
const {
|
||||||
propsRes: changeHistoryPropsRes,
|
propsRes: changeHistoryPropsRes,
|
||||||
propsEvent: changeHistoryPropsEvent,
|
propsEvent: changeHistoryPropsEvent,
|
||||||
loadList: changeHistoryloadList,
|
setLoadListParams: setHistoryLoadListParams,
|
||||||
setLoadListParams: changeHistorySetLoadListParams,
|
loadList: loadHistoryList,
|
||||||
resetSelector: changeHistoryResetSelector,
|
} = useTable(getChangeHistory, {
|
||||||
} = useTable(
|
columns: changeHistoryColumns,
|
||||||
() =>
|
tableKey: TableKeyEnum.PROJECT_MANAGEMENT_COMMON_SCRIPT_CHANGE_HISTORY,
|
||||||
Promise.resolve({
|
selectable: false,
|
||||||
list: [],
|
showSetting: false,
|
||||||
current: 1,
|
scroll: { x: '100%' },
|
||||||
pageSize: 10,
|
heightUsed: 300,
|
||||||
total: 2,
|
});
|
||||||
}),
|
|
||||||
{
|
|
||||||
columns: changeHistoryColumns,
|
|
||||||
tableKey: TableKeyEnum.PROJECT_MANAGEMENT_COMMON_SCRIPT_CHANGE_HISTORY,
|
|
||||||
selectable: false,
|
|
||||||
showSetting: false,
|
|
||||||
scroll: { x: '100%' },
|
|
||||||
heightUsed: 300,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function recoverHandler(record: any) {}
|
function recoverHandler(record: any) {}
|
||||||
|
|
||||||
|
@ -230,27 +251,37 @@
|
||||||
|
|
||||||
const form = ref<AddOrUpdateCommonScript>({ ...initForm });
|
const form = ref<AddOrUpdateCommonScript>({ ...initForm });
|
||||||
|
|
||||||
async function getDetail(scriptId: string) {
|
const detailValue = computed({
|
||||||
|
get: () => {
|
||||||
|
return scriptType.value === 'commonScript' ? form.value.script : form.value.result;
|
||||||
|
},
|
||||||
|
set: (val) => val,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getDetail() {
|
||||||
try {
|
try {
|
||||||
const result = await getCommonScriptDetail(scriptId);
|
const result = await getCommonScriptDetail(props.scriptId);
|
||||||
form.value = cloneDeep(result);
|
form.value = cloneDeep(result);
|
||||||
detailValue.value = form.value.script;
|
|
||||||
const innerTableData = JSON.parse(form.value.params);
|
const innerTableData = JSON.parse(form.value.params);
|
||||||
setProps({ data: innerTableData.slice(0, innerTableData.length - 1) });
|
propsRes.value.data = innerTableData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const originScript = ref<string>('');
|
|
||||||
|
|
||||||
watch(
|
function loadChangeHistoryPage() {
|
||||||
() => props.scriptId,
|
setHistoryLoadListParams({
|
||||||
(val) => {
|
projectId: appStore.getCurrentProjectId,
|
||||||
if (val && originScript.value !== val) {
|
sourceId: props.scriptId,
|
||||||
getDetail(val);
|
});
|
||||||
}
|
loadHistoryList();
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (props.scriptId) {
|
||||||
|
getDetail();
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => scriptType.value,
|
() => scriptType.value,
|
||||||
|
@ -260,8 +291,86 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
function editHandler() {
|
||||||
originScript.value = props.scriptId;
|
emit('update', props.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const websocket = ref<any>();
|
||||||
|
const reportId = ref('');
|
||||||
|
|
||||||
|
function testHandler() {
|
||||||
|
reportId.value = getGenerateId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
try {
|
||||||
|
const { type, script } = form.value;
|
||||||
|
const parameters = JSON.parse(form.value.params);
|
||||||
|
parameters
|
||||||
|
.filter((item: any) => item.key && item.value)
|
||||||
|
.map((item) => {
|
||||||
|
return {
|
||||||
|
key: item.key,
|
||||||
|
value: item.value,
|
||||||
|
valid: item.mustContain,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const params = {
|
||||||
|
type,
|
||||||
|
script,
|
||||||
|
params: parameters,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
reportId: reportId.value,
|
||||||
|
};
|
||||||
|
await testCommonScript(params);
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOpen() {
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugSocket() {
|
||||||
|
loading.value = true;
|
||||||
|
websocket.value = getSocket(reportId.value);
|
||||||
|
websocket.value.onopen = onOpen;
|
||||||
|
websocket.value.addEventListener('message', (event: any) => {
|
||||||
|
const result = JSON.parse(event.data);
|
||||||
|
if (result.msgType === 'EXEC_RESULT') {
|
||||||
|
form.value.result = result.taskResult.console;
|
||||||
|
scriptType.value = 'executionResult';
|
||||||
|
websocket.value.close();
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => reportId.value,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
debugSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => showType.value,
|
||||||
|
(val) => {
|
||||||
|
if (val === 'changeHistory') {
|
||||||
|
loadChangeHistoryPage();
|
||||||
|
} else {
|
||||||
|
getDetail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getDetail,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,12 @@
|
||||||
:enable-radio-selected="radioSelected"
|
:enable-radio-selected="radioSelected"
|
||||||
@save="saveHandler"
|
@save="saveHandler"
|
||||||
/>
|
/>
|
||||||
<ScriptDetailDrawer v-model:visible="showDetailDrawer" :script-id="scriptId" />
|
<ScriptDetailDrawer
|
||||||
|
ref="scriptDetailDrawer"
|
||||||
|
v-model:visible="showDetailDrawer"
|
||||||
|
:script-id="scriptId"
|
||||||
|
@update="updateHandler"
|
||||||
|
/>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -329,6 +334,7 @@
|
||||||
|
|
||||||
const paramsList = ref<ParamsRequestType[]>([]);
|
const paramsList = ref<ParamsRequestType[]>([]);
|
||||||
const confirmLoading = ref<boolean>(false);
|
const confirmLoading = ref<boolean>(false);
|
||||||
|
const scriptDetailDrawer = ref();
|
||||||
|
|
||||||
// 保存自定义代码片段应用
|
// 保存自定义代码片段应用
|
||||||
async function saveHandler(form: AddOrUpdateCommonScript) {
|
async function saveHandler(form: AddOrUpdateCommonScript) {
|
||||||
|
@ -351,6 +357,9 @@
|
||||||
? t('project.commonScript.saveDraftSuccessfully')
|
? t('project.commonScript.saveDraftSuccessfully')
|
||||||
: t('project.commonScript.appliedSuccessfully')
|
: t('project.commonScript.appliedSuccessfully')
|
||||||
);
|
);
|
||||||
|
if (showDetailDrawer.value) {
|
||||||
|
scriptDetailDrawer.value.getDetail();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -363,6 +372,11 @@
|
||||||
showScriptDrawer.value = true;
|
showScriptDrawer.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateHandler(id: string) {
|
||||||
|
isEditId.value = id;
|
||||||
|
showScriptDrawer.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
const radioSelected = ref<boolean>(false);
|
const radioSelected = ref<boolean>(false);
|
||||||
|
|
||||||
function editHandler(record: AddOrUpdateCommonScript) {
|
function editHandler(record: AddOrUpdateCommonScript) {
|
||||||
|
|
|
@ -65,4 +65,5 @@ export default {
|
||||||
'project.processor.terminationTest': 'Termination test',
|
'project.processor.terminationTest': 'Termination test',
|
||||||
'project.processor.code_hide_report_length': 'Hide report length',
|
'project.processor.code_hide_report_length': 'Hide report length',
|
||||||
'project.processor.code_add_report_length': 'Add report length to head',
|
'project.processor.code_add_report_length': 'Add report length to head',
|
||||||
|
'project.processor.current': 'current',
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,4 +66,5 @@ export default {
|
||||||
'project.processor.terminationTest': '终止测试',
|
'project.processor.terminationTest': '终止测试',
|
||||||
'project.processor.code_hide_report_length': '隐藏报文长度',
|
'project.processor.code_hide_report_length': '隐藏报文长度',
|
||||||
'project.processor.code_add_report_length': '报文头添加长度',
|
'project.processor.code_add_report_length': '报文头添加长度',
|
||||||
|
'project.processor.current': '当前',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue