fix: 修复接口测试报告bug&公共脚本bug&三方插件bug

This commit is contained in:
xinxin.wu 2024-04-06 10:41:55 +08:00 committed by 刘瑞斌
parent 1a2b88f7a2
commit d6cc864783
24 changed files with 371 additions and 186 deletions

View File

@ -3,6 +3,7 @@ import {
AddCommonScriptUrl,
ConnectionWebsocketUrl,
DeleteCommonScriptUrl,
getChangeHistoryUrl,
GetCommonScriptDetailUrl,
GetCommonScriptPageUrl,
GetCommonScriptStatusUrl,
@ -19,6 +20,7 @@ import type { ModulesTreeType } from '@/models/caseManagement/featureCase';
import { CommonList, TableQueryParams } from '@/models/common';
import type {
AddOrUpdateCommonScript,
changeHistory,
CommonScriptItem,
TestScriptType,
} from '@/models/projectManagement/commonScript';
@ -57,6 +59,10 @@ export function getCommonScriptStatus(data: AddOrUpdateCommonScript) {
export function getInsertCommonScriptPage(data: TableQueryParams) {
return MSR.post<CommonList<CommonScriptItem[]>>({ url: GetInsertCommonScriptPageUrl, data });
}
// 获取公共脚本变更历史详情
export function getChangeHistory(data: TableQueryParams) {
return MSR.post<CommonList<changeHistory[]>>({ url: getChangeHistoryUrl, data });
}
/**
*

View File

@ -25,3 +25,5 @@ export const GetFormApiImportModuleCountUrl = '/api/definition/module/count';
export const TestScriptUrl = '/api/test/custom/func/run';
// websoket连接
export const ConnectionWebsocketUrl = '/ws/api';
// 公共脚本变更历史详情
export const getChangeHistoryUrl = '/project/custom/func/history/page';

View File

@ -1,14 +1,5 @@
<template>
<div class="h-full w-full">
<a-scrollbar
:style="{
overflow: 'auto',
height: 'calc(100vh - 490px)',
}"
>
<conditionContent v-model:data="condition" :disabled="props.disabled" />
</a-scrollbar>
</div>
</template>
<script lang="ts" setup>
@ -38,12 +29,6 @@
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({});
async function initEnvironment() {

View File

@ -81,7 +81,6 @@
:style="{
overflow: 'auto',
height: '100%',
width: '100%',
}"
>
<!-- 响应头 -->
@ -123,13 +122,13 @@
@change="handleChange"
/>
<!-- 脚本 -->
</a-scrollbar>
<ScriptTab
v-if="getCurrentItemState.assertionType === ResponseAssertionType.SCRIPT"
v-model:data="getCurrentItemState"
:disabled="props.disabled"
@change="handleChange"
/>
</a-scrollbar>
</div>
</div>
</div>

View File

@ -383,7 +383,7 @@
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);
}

View File

@ -136,7 +136,7 @@ export const INT = {
};
export const MULTIPLE_INPUT = {
type: 'a-input-tag',
type: 'MsTagsInput',
field: 'fieldName',
title: '',
value: [],

View File

@ -15,6 +15,7 @@
*/
import { ref, watch, watchEffect } from 'vue';
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
import JiraKey from './comp/jiraKey.vue';
import PassWord from './formcreate-password.vue';
import SearchSelect from './searchSelect.vue';
@ -24,6 +25,7 @@
formCreate.component('PassWord', PassWord);
formCreate.component('SearchSelect', SearchSelect);
formCreate.component('JiraKey', JiraKey);
formCreate.component('MsTagsInput', MsTagsInput);
const FormCreate = formCreate.$form();
const props = defineProps<{

View File

@ -11,6 +11,7 @@
import { useVModel } from '@vueuse/core';
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 PassWord from './formcreate-password.vue';
import SearchSelect from './searchSelect.vue';
@ -27,6 +28,7 @@
formCreate.component('PassWord', PassWord);
formCreate.component('SearchSelect', SearchSelect);
formCreate.component('JiraKey', JiraKey);
formCreate.component('MsTagsInput', MsTagsInput);
const FormCreate = formCreate.$form();
//

View File

@ -1,4 +1,5 @@
<template>
<div class="w-full">
<div :class="`flex w-full items-center ${props.class}`">
<a-input-tag
v-model:model-value="innerModelValue"
@ -29,9 +30,10 @@
</template>
</a-input-tag>
</div>
<span v-if="isError" class="ml-[1px] text-[12px] text-[rgb(var(--danger-6))]">
<div v-if="isError" class="ml-[1px] flex justify-start text-[12px] text-[rgb(var(--danger-6))]">
{{ t('common.tagInputMaxLength', { number: props.maxLength }) }}
</span>
</div>
</div>
</template>
<script setup lang="ts">

View File

@ -105,6 +105,7 @@ export interface ScenarioItemType {
children: ScenarioItemType[];
level?: number;
stepDetail: ReportStepDetailItem;
stepChildren?: ScenarioItemType[]; // 步骤子步骤
}
export type ScenarioDetailItem = Partial<ScenarioItemType>;

View File

@ -66,3 +66,16 @@ export interface TestScriptType {
script: 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;
}

View File

@ -17,7 +17,7 @@
<slot name="titleRight"></slot>
</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]">
<conditionList
v-model:list="data"

View File

@ -310,14 +310,16 @@
const isShowLoopControl = computed(() => {
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 controlTotal = computed(() => {
if (props.stepItem?.children) {
return props.stepItem.children.length || 0;
if (props.stepItem?.stepChildren) {
return props.stepItem?.stepChildren.length || 0;
}
return 0;
});
@ -326,8 +328,8 @@
* 循环次数控制器
*/
function loadControlLoop() {
if (isShowLoopControl.value) {
const loopStepId = props.stepItem?.children[controlCurrent.value - 1].stepId;
if (isShowLoopControl.value && props.stepItem?.stepChildren) {
const loopStepId = props.stepItem?.stepChildren[controlCurrent.value - 1].stepId;
if (loopStepId) {
getStepDetail(loopStepId);
}
@ -340,8 +342,8 @@
() => props.stepItem?.stepId,
(val) => {
if (val) {
if (isShowLoopControl.value) {
getStepDetail(props.stepItem?.children[controlCurrent.value - 1].stepId as string);
if (isShowLoopControl.value && props.stepItem?.stepChildren) {
getStepDetail(props.stepItem?.stepChildren[controlCurrent.value - 1].stepId as string);
} else {
getStepDetail(val);
}

View File

@ -58,7 +58,7 @@
required: true,
});
const reportStepDetail = ref<ReportDetail>({
const initReportStepDetail = {
id: '',
name: '', //
testPlanId: '',
@ -96,6 +96,9 @@
children: [], //
stepTotal: 0, //
console: '',
};
const reportStepDetail = ref<ReportDetail>({
...initReportStepDetail,
});
async function getReportCaseDetail() {
try {
@ -110,6 +113,7 @@
() => innerVisible.value,
async (val) => {
if (val) {
reportStepDetail.value = { ...initReportStepDetail };
await getReportCaseDetail();
}
}

View File

@ -3,13 +3,39 @@
<div class="relative mr-4">
<div class="charts absolute text-center">
<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>
<MsChart width="110px" height="110px" :options="props.options" />
<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>
<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 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="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>
@ -30,9 +56,12 @@
import MsChart from '@/components/pure/chart/index.vue';
import { useI18n } from '@/hooks/useI18n';
import { addCommasToNumber, formatDuration } from '@/utils';
import type { LegendData } from '@/models/apiTest/report';
import { getIndicators } from '../../utils';
const { t } = useI18n();
const props = defineProps<{
options: Record<string, any>;
@ -58,6 +87,7 @@
right: 0;
bottom: 0;
left: 0;
z-index: 99;
margin: auto;
}
</style>

View File

@ -228,6 +228,7 @@
const charOptions = ref({
tooltip: {
trigger: 'item',
show: false,
},
legend: {
show: false,

View File

@ -195,10 +195,6 @@
reportStepDetail.value = cloneDeep(detail);
}
onBeforeUnmount(() => {
detailDrawerRef.value?.destroy();
});
watch(
() => showDrawer.value,
(val) => {

View File

@ -203,10 +203,6 @@
const detailDrawerRef = ref();
onBeforeUnmount(() => {
detailDrawerRef.value?.destroy();
});
watch(
() => showDrawer.value,
(val) => {

View File

@ -47,8 +47,12 @@
</div>
<div>
<a-popover position="bottom" content-class="response-popover-content">
<span class="ml-4 text-[18px] font-medium">{{ getTotalTime.split('-')[0] || '-' }}</span>
<span class="ml-1 text-[var(--color-text-4)]">{{ getTotalTime.split('-')[1] || 'ms' }}</span>
<div class="flex items-center">
<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>
<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>
@ -68,7 +72,7 @@
</div>
<div>
<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] : '-'
}}</span>
@ -147,26 +151,11 @@
<div class="request-analyze">
<div class="block-title">{{ t('report.detail.api.requestAnalysis') }}</div>
<div class="flex min-h-[110px] items-center">
<div class="relative mr-4">
<div class="charts absolute text-center">
<div class="text-[12px] text-[(var(--color-text-4))]">{{ t('report.detail.api.total') }}</div>
<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>
<SetReportChart
:legend-data="legendData"
:options="charOptions"
:request-total="getIndicators(detail.requestTotal)"
/>
</div>
</div>
<!-- 报告步骤分析和请求分析结束 -->
@ -182,10 +171,9 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import dayjs from 'dayjs';
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 reportInfoHeader from './step/reportInfoHeaders.vue';
import StepProgress from './stepProgress.vue';
@ -265,6 +253,7 @@
const legendData = ref<LegendData[]>([]);
const charOptions = ref({
tooltip: {
show: false,
trigger: 'item',
},
legend: {
@ -449,6 +438,7 @@
right: 0;
bottom: 0;
left: 0;
z-index: 99;
margin: auto;
}
</style>

View File

@ -18,6 +18,7 @@
isStaticItemHeight: true,
estimatedSize: 48,
}"
:animation="false"
action-on-node-click="expand"
disabled-title-tooltip
block-node
@ -26,7 +27,8 @@
@more-actions-close="() => setFocusNodeKey('')"
>
<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 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
:type="step.expanded ? 'icon-icon_split_turn-down_arrow' : 'icon-icon_split-turn-down-left'"
:size="14"
@ -66,8 +71,14 @@
</div>
<a-tooltip :content="step.name" position="tl">
<div class="step-name-container w-full flex-grow" @click.stop="showDetail(step)">
<div class="one-line-text mx-[4px] max-w-[150px] text-[var(--color-text-1)]">
<div
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 }}
</div>
</div>
@ -186,6 +197,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { cloneDeep } from 'lodash-es';
import { MsTreeExpandedData } from '@/components/business/ms-tree/types';
@ -226,14 +238,19 @@
const innerExpandedKeys = defineModel<(string | number)[]>('expandedKeys', {
required: false,
});
const showApiType = ref<string[]>([ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST]);
const innerNumber = ref<number>(0);
/**
* 处理步骤展开折叠
*/
function handleStepExpand(data: MsTreeExpandedData) {
const realStep = findNodeByKey<ScenarioItemType>(steps.value, data.node?.stepId, 'stepId');
if (realStep) {
realStep.expanded = !realStep.expanded;
const isNotAllowExpand =
data.node?.children && data.node?.children.length && showApiType.value.includes(data.node?.stepType);
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) {
const realStep = findNodeByKey<ScenarioItemType>(steps.value, item.stepId, 'stepId');
// TODO
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;
}
}
const showApiType = ref<string[]>([ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST]);
const showCondition = ref<string[]>([
ScenarioStepType.API,
ScenarioStepType.API_CASE,
@ -276,7 +298,7 @@
return props.activeType === 'tab';
}
const activeItem = ref();
function showDetail(item: ScenarioItemType) {
function showDetail(event: Event, item: ScenarioItemType) {
if (props.activeType === 'tab') {
return;
}
@ -285,6 +307,7 @@
}
activeItem.value = item;
emit('detail', activeItem.value);
event.stopPropagation();
}
//
@ -315,6 +338,12 @@
}
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>
<style scoped lang="less">

View File

@ -1,14 +1,32 @@
<template>
<MsDrawer
v-model:visible="scriptDetailDrawer"
:title="t('project.commonScript.publicScriptName')"
:width="768"
:footer="false"
unmount-on-close
>
<MsDrawer v-model:visible="scriptDetailDrawer" :title="form.name" :width="800" :footer="false" unmount-on-close>
<template #headerLeft>
<MsTag class="ml-1" type="success" theme="light">{{ t('project.commonScript.testSuccess') }}</MsTag>
</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 value="detail">{{ t('project.commonScript.detail') }}</a-radio>
<a-radio value="changeHistory">{{ t('project.commonScript.changeHistory') }}</a-radio>
@ -27,11 +45,11 @@
</span>
</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">
<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>
</ms-base-table>
@ -46,7 +64,7 @@
width="100%"
height="calc(100vh - 155px)"
theme="MS-text"
:read-only="false"
:read-only="true"
:show-full-screen="false"
:show-theme-change="false"
/>
@ -55,12 +73,15 @@
v-else
v-bind="changeHistoryPropsRes"
ref="tableRef"
class="mb-4"
class="mt-4"
no-disable
v-on="changeHistoryPropsEvent"
>
<template #changeSerialNumber="{ record }"
><div class="flex items-center"> {{ record.changeSerialNumber }} <MsTag>当前</MsTag> </div>
<template #id="{ record }">
<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 #operation="{ record }">
<MsButton status="primary" @click="recoverHandler(record)">
@ -84,12 +105,21 @@
import useTable from '@/components/pure/ms-table/useTable';
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 useAppStore from '@/store/modules/app';
import { getGenerateId } from '@/utils';
import type { AddOrUpdateCommonScript } from '@/models/projectManagement/commonScript';
import { TableKeyEnum } from '@/enums/tableEnum';
const appStore = useAppStore();
const { t } = useI18n();
const props = defineProps<{
@ -97,7 +127,7 @@
scriptId: string; // id
}>();
const emit = defineEmits(['update:visible', 'change']);
const emit = defineEmits(['update:visible', 'change', 'update']);
const showType = ref('detail');
@ -113,8 +143,8 @@
const columns: MsTableColumn = [
{
title: 'project.commonScript.ParameterNames',
slotName: 'name',
dataIndex: 'name',
slotName: 'key',
dataIndex: 'key',
showTooltip: true,
showInTable: true,
},
@ -127,8 +157,8 @@
},
{
title: 'project.commonScript.description',
slotName: 'desc',
dataIndex: 'desc',
slotName: 'description',
dataIndex: 'description',
showTooltip: true,
},
{
@ -139,7 +169,7 @@
},
];
const { propsRes, propsEvent, setProps } = useTable(undefined, {
const { propsRes, propsEvent } = useTable(undefined, {
columns,
selectable: false,
showSetting: false,
@ -149,70 +179,61 @@
const scriptType = ref<'commonScript' | 'executionResult'>('commonScript');
const detailValue = ref('');
const changeHistoryColumns: MsTableColumn = [
{
title: 'project.commonScript.changeSerialNumber',
slotName: 'changeSerialNumber',
dataIndex: 'changeSerialNumber',
slotName: 'id',
dataIndex: 'id',
showTooltip: true,
showInTable: true,
width: 300,
},
{
title: 'project.commonScript.actionType',
slotName: 'actionType',
dataIndex: 'actionType',
slotName: 'type',
dataIndex: 'type',
showInTable: true,
width: 200,
},
{
title: 'project.commonScript.actionUser',
dataIndex: 'actionUser',
slotName: 'actionUser',
dataIndex: 'createUserName',
slotName: 'createUserName',
showTooltip: true,
showInTable: true,
},
{
title: 'project.commonScript.updateTime',
dataIndex: 'updateTime',
slotName: 'updateTime',
dataIndex: 'createTime',
slotName: 'createTime',
showTooltip: true,
showInTable: true,
},
{
title: 'project.commonScript.tableColumnActions',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 140,
showInTable: true,
showDrag: false,
},
// TODO:
// {
// title: 'project.commonScript.tableColumnActions',
// slotName: 'operation',
// dataIndex: 'operation',
// fixed: 'right',
// width: 140,
// showInTable: true,
// showDrag: false,
// },
];
const {
propsRes: changeHistoryPropsRes,
propsEvent: changeHistoryPropsEvent,
loadList: changeHistoryloadList,
setLoadListParams: changeHistorySetLoadListParams,
resetSelector: changeHistoryResetSelector,
} = useTable(
() =>
Promise.resolve({
list: [],
current: 1,
pageSize: 10,
total: 2,
}),
{
setLoadListParams: setHistoryLoadListParams,
loadList: loadHistoryList,
} = useTable(getChangeHistory, {
columns: changeHistoryColumns,
tableKey: TableKeyEnum.PROJECT_MANAGEMENT_COMMON_SCRIPT_CHANGE_HISTORY,
selectable: false,
showSetting: false,
scroll: { x: '100%' },
heightUsed: 300,
}
);
});
function recoverHandler(record: any) {}
@ -230,27 +251,37 @@
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 {
const result = await getCommonScriptDetail(scriptId);
const result = await getCommonScriptDetail(props.scriptId);
form.value = cloneDeep(result);
detailValue.value = form.value.script;
const innerTableData = JSON.parse(form.value.params);
setProps({ data: innerTableData.slice(0, innerTableData.length - 1) });
propsRes.value.data = innerTableData;
} catch (error) {
console.log(error);
}
}
const originScript = ref<string>('');
watch(
() => props.scriptId,
(val) => {
if (val && originScript.value !== val) {
getDetail(val);
function loadChangeHistoryPage() {
setHistoryLoadListParams({
projectId: appStore.getCurrentProjectId,
sourceId: props.scriptId,
});
loadHistoryList();
}
watchEffect(() => {
if (props.scriptId) {
getDetail();
}
);
});
watch(
() => scriptType.value,
@ -260,8 +291,86 @@
}
);
onMounted(() => {
originScript.value = props.scriptId;
function editHandler() {
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>

View File

@ -99,7 +99,12 @@
:enable-radio-selected="radioSelected"
@save="saveHandler"
/>
<ScriptDetailDrawer v-model:visible="showDetailDrawer" :script-id="scriptId" />
<ScriptDetailDrawer
ref="scriptDetailDrawer"
v-model:visible="showDetailDrawer"
:script-id="scriptId"
@update="updateHandler"
/>
</MsCard>
</template>
@ -329,6 +334,7 @@
const paramsList = ref<ParamsRequestType[]>([]);
const confirmLoading = ref<boolean>(false);
const scriptDetailDrawer = ref();
//
async function saveHandler(form: AddOrUpdateCommonScript) {
@ -351,6 +357,9 @@
? t('project.commonScript.saveDraftSuccessfully')
: t('project.commonScript.appliedSuccessfully')
);
if (showDetailDrawer.value) {
scriptDetailDrawer.value.getDetail();
}
} catch (error) {
console.log(error);
} finally {
@ -363,6 +372,11 @@
showScriptDrawer.value = true;
}
function updateHandler(id: string) {
isEditId.value = id;
showScriptDrawer.value = true;
}
const radioSelected = ref<boolean>(false);
function editHandler(record: AddOrUpdateCommonScript) {

View File

@ -65,4 +65,5 @@ export default {
'project.processor.terminationTest': 'Termination test',
'project.processor.code_hide_report_length': 'Hide report length',
'project.processor.code_add_report_length': 'Add report length to head',
'project.processor.current': 'current',
};

View File

@ -66,4 +66,5 @@ export default {
'project.processor.terminationTest': '终止测试',
'project.processor.code_hide_report_length': '隐藏报文长度',
'project.processor.code_add_report_length': '报文头添加长度',
'project.processor.current': '当前',
};